mirror of
https://github.com/billsonnn/nitro-react.git
synced 2024-11-23 14:40:50 +01:00
Merge branch 'dev' into @update/groups
This commit is contained in:
commit
dede68f5e6
@ -11,6 +11,7 @@
|
|||||||
"chat.viewer.height.percentage": 0.40,
|
"chat.viewer.height.percentage": 0.40,
|
||||||
"widget.dimmer.colorwheel": false,
|
"widget.dimmer.colorwheel": false,
|
||||||
"avatar.wardrobe.max.slots": 10,
|
"avatar.wardrobe.max.slots": 10,
|
||||||
|
"user.badges.max.slots": 5,
|
||||||
"hotelview": {
|
"hotelview": {
|
||||||
"widgets": {
|
"widgets": {
|
||||||
"slot.1.widget": "promoarticle",
|
"slot.1.widget": "promoarticle",
|
||||||
|
@ -32,7 +32,7 @@ $inventory-height: 320px;
|
|||||||
$navigator-width: 400px;
|
$navigator-width: 400px;
|
||||||
$navigator-height: 420px;
|
$navigator-height: 420px;
|
||||||
|
|
||||||
$chat-input-style-selector-widget-width: 200px;
|
$chat-input-style-selector-widget-width: 210px;
|
||||||
$chat-input-style-selector-widget-height: 200px;
|
$chat-input-style-selector-widget-height: 200px;
|
||||||
|
|
||||||
$user-profile-width: 560px;
|
$user-profile-width: 560px;
|
||||||
@ -75,6 +75,9 @@ $nitro-mod-tools-width: 175px;
|
|||||||
$nitro-group-manager-width: 375px;
|
$nitro-group-manager-width: 375px;
|
||||||
$nitro-group-manager-height: 355px;
|
$nitro-group-manager-height: 355px;
|
||||||
|
|
||||||
|
$nitro-chooser-width: 200px;
|
||||||
|
$nitro-chooser-height: 200px;
|
||||||
|
|
||||||
.nitro-app {
|
.nitro-app {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -97,3 +97,24 @@ ul {
|
|||||||
background-color: $table-striped-bg;
|
background-color: $table-striped-bg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes bounceIn {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(.3);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
70% {
|
||||||
|
transform: scale(.9);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
pointer-events: all;
|
||||||
|
}
|
||||||
|
@ -13,13 +13,14 @@ export interface BaseProps<T = HTMLElement> extends DetailedHTMLProps<HTMLAttrib
|
|||||||
position?: PositionType;
|
position?: PositionType;
|
||||||
float?: FloatType;
|
float?: FloatType;
|
||||||
pointer?: boolean;
|
pointer?: boolean;
|
||||||
|
visible?: boolean;
|
||||||
textColor?: ColorVariantType;
|
textColor?: ColorVariantType;
|
||||||
classNames?: string[];
|
classNames?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Base: FC<BaseProps<HTMLDivElement>> = props =>
|
export const Base: FC<BaseProps<HTMLDivElement>> = props =>
|
||||||
{
|
{
|
||||||
const { ref = null, innerRef = null, fit = false, grow = false, shrink = false, fullWidth = false, fullHeight = false, overflow = null, position = null, float = null, pointer = false, textColor = null, classNames = [], className = '', style = {}, ...rest } = props;
|
const { ref = null, innerRef = null, fit = false, grow = false, shrink = false, fullWidth = false, fullHeight = false, overflow = null, position = null, float = null, pointer = false, visible = null, textColor = null, classNames = [], className = '', style = {}, ...rest } = props;
|
||||||
|
|
||||||
const getClassNames = useMemo(() =>
|
const getClassNames = useMemo(() =>
|
||||||
{
|
{
|
||||||
@ -41,12 +42,14 @@ export const Base: FC<BaseProps<HTMLDivElement>> = props =>
|
|||||||
|
|
||||||
if(pointer) newClassNames.push('cursor-pointer');
|
if(pointer) newClassNames.push('cursor-pointer');
|
||||||
|
|
||||||
|
if(visible !== null) newClassNames.push(visible ? 'visible' : 'invisible');
|
||||||
|
|
||||||
if(textColor) newClassNames.push('text-' + textColor);
|
if(textColor) newClassNames.push('text-' + textColor);
|
||||||
|
|
||||||
if(classNames.length) newClassNames.push(...classNames);
|
if(classNames.length) newClassNames.push(...classNames);
|
||||||
|
|
||||||
return newClassNames;
|
return newClassNames;
|
||||||
}, [ fit, grow, shrink, fullWidth, fullHeight, overflow, position, float, pointer, textColor, classNames ]);
|
}, [ fit, grow, shrink, fullWidth, fullHeight, overflow, position, float, pointer, visible, textColor, classNames ]);
|
||||||
|
|
||||||
const getClassName = useMemo(() =>
|
const getClassName = useMemo(() =>
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { FC, useMemo } from 'react';
|
import { CSSProperties, FC, useMemo } from 'react';
|
||||||
import { CSSProperties } from 'styled-components';
|
|
||||||
import { Base, BaseProps } from './Base';
|
import { Base, BaseProps } from './Base';
|
||||||
import { GridContextProvider } from './GridContext';
|
import { GridContextProvider } from './GridContext';
|
||||||
import { AlignItemType, AlignSelfType, JustifyContentType, SpacingType } from './types';
|
import { AlignItemType, AlignSelfType, JustifyContentType, SpacingType } from './types';
|
||||||
|
@ -1 +1 @@
|
|||||||
export type OverflowType = 'hidden' | 'auto' | 'unset';
|
export type OverflowType = 'auto' | 'hidden' | 'visible' | 'scroll' | 'unset';
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { IFurnitureData } from '@nitrots/nitro-renderer';
|
import { GetProductOfferComposer, IFurnitureData } from '@nitrots/nitro-renderer';
|
||||||
import { GetProductDataForLocalization } from '../../../api';
|
import { GetProductDataForLocalization } from '../../../api';
|
||||||
|
import { SendMessageHook } from '../../../hooks';
|
||||||
import { ICatalogPage } from './ICatalogPage';
|
import { ICatalogPage } from './ICatalogPage';
|
||||||
import { IProduct } from './IProduct';
|
import { IProduct } from './IProduct';
|
||||||
import { IPurchasableOffer } from './IPurchasableOffer';
|
import { IPurchasableOffer } from './IPurchasableOffer';
|
||||||
@ -18,6 +19,11 @@ export class FurnitureOffer implements IPurchasableOffer
|
|||||||
this._product = (new Product(this._furniData.type, this._furniData.id, this._furniData.customParams, 1, GetProductDataForLocalization(this._furniData.className), this._furniData) as IProduct);
|
this._product = (new Product(this._furniData.type, this._furniData.id, this._furniData.customParams, 1, GetProductDataForLocalization(this._furniData.className), this._furniData) as IProduct);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public activate(): void
|
||||||
|
{
|
||||||
|
SendMessageHook(new GetProductOfferComposer((this._furniData.rentOfferId > -1) ? this._furniData.rentOfferId : this._furniData.purchaseOfferId));
|
||||||
|
}
|
||||||
|
|
||||||
public get offerId(): number
|
public get offerId(): number
|
||||||
{
|
{
|
||||||
return (this.isRentOffer) ? this._furniData.rentOfferId : this._furniData.purchaseOfferId;
|
return (this.isRentOffer) ? this._furniData.rentOfferId : this._furniData.purchaseOfferId;
|
||||||
@ -107,4 +113,9 @@ export class FurnitureOffer implements IPurchasableOffer
|
|||||||
{
|
{
|
||||||
return this._furniData.description;
|
return this._furniData.description;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public get isLazy(): boolean
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ import { IProduct } from './IProduct';
|
|||||||
|
|
||||||
export interface IPurchasableOffer
|
export interface IPurchasableOffer
|
||||||
{
|
{
|
||||||
|
activate(): void;
|
||||||
clubLevel: number;
|
clubLevel: number;
|
||||||
page: ICatalogPage;
|
page: ICatalogPage;
|
||||||
offerId: number;
|
offerId: number;
|
||||||
@ -19,5 +20,6 @@ export interface IPurchasableOffer
|
|||||||
badgeCode: string;
|
badgeCode: string;
|
||||||
localizationName: string;
|
localizationName: string;
|
||||||
localizationDescription: string;
|
localizationDescription: string;
|
||||||
|
isLazy: boolean;
|
||||||
products: IProduct[];
|
products: IProduct[];
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,11 @@ export class Offer implements IPurchasableOffer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public activate(): void
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public get clubLevel(): number
|
public get clubLevel(): number
|
||||||
{
|
{
|
||||||
return this._clubLevel;
|
return this._clubLevel;
|
||||||
@ -160,6 +165,11 @@ export class Offer implements IPurchasableOffer
|
|||||||
return LocalizeText(this._localizationId);
|
return LocalizeText(this._localizationId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public get isLazy(): boolean
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public get products(): IProduct[]
|
public get products(): IProduct[]
|
||||||
{
|
{
|
||||||
return this._products;
|
return this._products;
|
||||||
|
@ -78,8 +78,6 @@ export const CatalogLayoutPetView: FC<CatalogLayoutProps> = props =>
|
|||||||
{
|
{
|
||||||
let key: string = '';
|
let key: string = '';
|
||||||
|
|
||||||
console.log(approvalResult);
|
|
||||||
|
|
||||||
switch(approvalResult)
|
switch(approvalResult)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -21,6 +21,10 @@ export const CatalogItemGridWidgetView: FC<CatalogItemGridWidgetViewProps> = pro
|
|||||||
|
|
||||||
const selectOffer = (offer: IPurchasableOffer) =>
|
const selectOffer = (offer: IPurchasableOffer) =>
|
||||||
{
|
{
|
||||||
|
offer.activate();
|
||||||
|
|
||||||
|
if(offer.isLazy) return;
|
||||||
|
|
||||||
setCurrentOffer(offer);
|
setCurrentOffer(offer);
|
||||||
|
|
||||||
if(offer.product && (offer.product.productType === ProductTypeEnum.WALL))
|
if(offer.product && (offer.product.productType === ProductTypeEnum.WALL))
|
||||||
@ -31,10 +35,7 @@ export const CatalogItemGridWidgetView: FC<CatalogItemGridWidgetViewProps> = pro
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<AutoGrid columnCount={ columnCount } { ...rest }>
|
<AutoGrid columnCount={ columnCount } { ...rest }>
|
||||||
{ currentPage.offers && (currentPage.offers.length > 0) && currentPage.offers.map((offer, index) =>
|
{ currentPage.offers && (currentPage.offers.length > 0) && currentPage.offers.map((offer, index) => <CatalogGridOfferView key={ index } itemActive={ (currentOffer && (currentOffer.offerId === offer.offerId)) } offer={ offer } onClick={ event => selectOffer(offer) } />) }
|
||||||
{
|
|
||||||
return <CatalogGridOfferView key={ index } itemActive={ (currentOffer && (currentOffer.offerId === offer.offerId)) } offer={ offer } onClick={ event => selectOffer(offer) } />;
|
|
||||||
}) }
|
|
||||||
{ children }
|
{ children }
|
||||||
</AutoGrid>
|
</AutoGrid>
|
||||||
);
|
);
|
||||||
|
@ -106,15 +106,15 @@ export const CatalogPurchaseWidgetView: FC<CatalogPurchaseWidgetViewProps> = pro
|
|||||||
|
|
||||||
let pageId = currentOffer.page.pageId;
|
let pageId = currentOffer.page.pageId;
|
||||||
|
|
||||||
if(pageId === -1)
|
// if(pageId === -1)
|
||||||
{
|
// {
|
||||||
const nodes = getNodesByOfferId(currentOffer.offerId);
|
// const nodes = getNodesByOfferId(currentOffer.offerId);
|
||||||
|
|
||||||
if(nodes) pageId = nodes[0].pageId;
|
// if(nodes) pageId = nodes[0].pageId;
|
||||||
}
|
// }
|
||||||
|
|
||||||
SendMessageHook(new PurchaseFromCatalogComposer(pageId, currentOffer.offerId, extraData, quantity));
|
SendMessageHook(new PurchaseFromCatalogComposer(pageId, currentOffer.offerId, extraData, quantity));
|
||||||
}, [ currentOffer, purchaseCallback, extraData, quantity, getNodesByOfferId ]);
|
}, [ currentOffer, purchaseCallback, extraData, quantity ]);
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
|
@ -1,8 +1,4 @@
|
|||||||
.nitro-chat-history {
|
.nitro-chat-history {
|
||||||
width: $chat-history-width;
|
width: $chat-history-width;
|
||||||
height: $chat-history-height;
|
height: $chat-history-height;
|
||||||
|
|
||||||
.content-area {
|
|
||||||
min-height: 200px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -227,8 +227,6 @@ export const InventoryMessageHandler: FC<{}> = props =>
|
|||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
|
|
||||||
console.log(parser);
|
|
||||||
|
|
||||||
dispatchFurnitureState({
|
dispatchFurnitureState({
|
||||||
type: InventoryFurnitureActions.UPDATE_TRADE,
|
type: InventoryFurnitureActions.UPDATE_TRADE,
|
||||||
payload: {
|
payload: {
|
||||||
@ -292,8 +290,6 @@ export const InventoryMessageHandler: FC<{}> = props =>
|
|||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
|
|
||||||
console.log(parser);
|
|
||||||
|
|
||||||
NotificationUtilities.simpleAlert(LocalizeText(`inventory.trading.openfail.${ parser.reason }`, [ 'otherusername' ], [ parser.otherUserName ]), null, null, null, LocalizeText('inventory.trading.openfail.title'));
|
NotificationUtilities.simpleAlert(LocalizeText(`inventory.trading.openfail.${ parser.reason }`, [ 'otherusername' ], [ parser.otherUserName ]), null, null, null, LocalizeText('inventory.trading.openfail.title'));
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { RequestBadgesComposer } from '@nitrots/nitro-renderer';
|
import { RequestBadgesComposer } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useEffect } from 'react';
|
import { FC, useEffect } from 'react';
|
||||||
import { LocalizeBadgeName, LocalizeText } from '../../../../api';
|
import { GetConfiguration, LocalizeBadgeName, LocalizeText } from '../../../../api';
|
||||||
import { AutoGrid } from '../../../../common/AutoGrid';
|
import { AutoGrid } from '../../../../common/AutoGrid';
|
||||||
import { Button } from '../../../../common/Button';
|
import { Button } from '../../../../common/Button';
|
||||||
import { Column } from '../../../../common/Column';
|
import { Column } from '../../../../common/Column';
|
||||||
@ -22,9 +22,10 @@ export const InventoryBadgeView: FC<InventoryBadgeViewProps> = props =>
|
|||||||
const { badgeState = null, dispatchBadgeState = null } = useInventoryContext();
|
const { badgeState = null, dispatchBadgeState = null } = useInventoryContext();
|
||||||
const { needsBadgeUpdate = false, badge = null, badges = [], activeBadges = [] } = badgeState;
|
const { needsBadgeUpdate = false, badge = null, badges = [], activeBadges = [] } = badgeState;
|
||||||
|
|
||||||
const isWearingBadge = (badgeCode: string) => (activeBadges.indexOf(badgeCode) >= 0);
|
const maxBadgeCount = GetConfiguration<number>('user.badges.max.slots', 5);
|
||||||
|
|
||||||
const canWearBadges = () => (activeBadges.length < 5);
|
const isWearingBadge = (badgeCode: string) => (activeBadges.indexOf(badgeCode) >= 0);
|
||||||
|
const canWearBadges = () => (activeBadges.length < maxBadgeCount);
|
||||||
|
|
||||||
const toggleBadge = () =>
|
const toggleBadge = () =>
|
||||||
{
|
{
|
||||||
|
@ -4,8 +4,8 @@ import { useNitroCardContext } from '../context';
|
|||||||
|
|
||||||
export const NitroCardContentView: FC<ColumnProps> = props =>
|
export const NitroCardContentView: FC<ColumnProps> = props =>
|
||||||
{
|
{
|
||||||
const { classNames = [], ...rest } = props;
|
const { overflow = 'auto', classNames = [], ...rest } = props;
|
||||||
const { theme = 'primary', simple = false } = useNitroCardContext();
|
const { simple = false } = useNitroCardContext();
|
||||||
|
|
||||||
const getClassNames = useMemo(() =>
|
const getClassNames = useMemo(() =>
|
||||||
{
|
{
|
||||||
@ -18,5 +18,5 @@ export const NitroCardContentView: FC<ColumnProps> = props =>
|
|||||||
return newClassNames;
|
return newClassNames;
|
||||||
}, [ simple, classNames ]);
|
}, [ simple, classNames ]);
|
||||||
|
|
||||||
return <Column classNames={ getClassNames } overflow="auto" { ...rest } />;
|
return <Column classNames={ getClassNames } overflow={ overflow } { ...rest } />;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,15 @@ import { FC, useCallback } from 'react';
|
|||||||
import { GetRoomEngine, GetSessionDataManager } from '../../../../api';
|
import { GetRoomEngine, GetSessionDataManager } from '../../../../api';
|
||||||
import { NitroLayoutFlexColumn } from '../../../../layout';
|
import { NitroLayoutFlexColumn } from '../../../../layout';
|
||||||
import { CalendarItemState } from '../../common/CalendarItemState';
|
import { CalendarItemState } from '../../common/CalendarItemState';
|
||||||
import { CalendarItemViewProps } from './CalendarItemView.types';
|
|
||||||
|
interface CalendarItemViewProps
|
||||||
|
{
|
||||||
|
id: number;
|
||||||
|
productName?: string;
|
||||||
|
state: number;
|
||||||
|
active?: boolean;
|
||||||
|
onClick(itemId: number): void;
|
||||||
|
}
|
||||||
|
|
||||||
export const CalendarItemView: FC<CalendarItemViewProps> = props =>
|
export const CalendarItemView: FC<CalendarItemViewProps> = props =>
|
||||||
{
|
{
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
export interface CalendarItemViewProps
|
|
||||||
{
|
|
||||||
id: number;
|
|
||||||
productName?: string;
|
|
||||||
state: number;
|
|
||||||
active?: boolean;
|
|
||||||
onClick(itemId: number): void;
|
|
||||||
}
|
|
@ -4,7 +4,18 @@ import { NitroCardContentView, NitroCardHeaderView, NitroCardView, NitroLayoutFl
|
|||||||
import { CalendarItemState } from '../../common/CalendarItemState';
|
import { CalendarItemState } from '../../common/CalendarItemState';
|
||||||
import { getNumItemsDisplayed } from '../../common/Utils';
|
import { getNumItemsDisplayed } from '../../common/Utils';
|
||||||
import { CalendarItemView } from '../calendar-item/CalendarItemView';
|
import { CalendarItemView } from '../calendar-item/CalendarItemView';
|
||||||
import { CalendarViewProps } from './CalendarView.types';
|
|
||||||
|
interface CalendarViewProps
|
||||||
|
{
|
||||||
|
close(): void;
|
||||||
|
openPackage(id: number, asStaff: boolean): void;
|
||||||
|
receivedProducts: Map<number, string>;
|
||||||
|
campaignName: string;
|
||||||
|
currentDay: number;
|
||||||
|
numDays: number;
|
||||||
|
openedDays: number[];
|
||||||
|
missedDays: number[];
|
||||||
|
}
|
||||||
|
|
||||||
export const CalendarView: FC<CalendarViewProps> = props =>
|
export const CalendarView: FC<CalendarViewProps> = props =>
|
||||||
{
|
{
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
export interface CalendarViewProps
|
|
||||||
{
|
|
||||||
close(): void;
|
|
||||||
openPackage(id: number, asStaff: boolean): void;
|
|
||||||
receivedProducts: Map<number, string>;
|
|
||||||
campaignName: string;
|
|
||||||
currentDay: number;
|
|
||||||
numDays: number;
|
|
||||||
openedDays: number[];
|
|
||||||
missedDays: number[];
|
|
||||||
}
|
|
@ -73,8 +73,6 @@ export class NotificationUtilities
|
|||||||
|
|
||||||
if(configuration) for(const key in configuration) options.set(key, configuration[key]);
|
if(configuration) for(const key in configuration) options.set(key, configuration[key]);
|
||||||
|
|
||||||
console.log(options);
|
|
||||||
|
|
||||||
const title = this.getNotificationPart(options, type, 'title', true);
|
const title = this.getNotificationPart(options, type, 'title', true);
|
||||||
const message = this.getNotificationPart(options, type, 'message', true).replace(/\\r/g, '\r');
|
const message = this.getNotificationPart(options, type, 'message', true).replace(/\\r/g, '\r');
|
||||||
const linkTitle = this.getNotificationPart(options, type, 'linkTitle', false);
|
const linkTitle = this.getNotificationPart(options, type, 'linkTitle', false);
|
||||||
|
@ -1,12 +1,104 @@
|
|||||||
|
.nitro-room-tools-container {
|
||||||
|
position: absolute;
|
||||||
|
bottom: $toolbar-height + 65px;
|
||||||
|
left: 0;
|
||||||
|
|
||||||
|
.nitro-room-tools {
|
||||||
|
background: rgba($dark,.95);
|
||||||
|
box-shadow: inset 0px 5px lighten(rgba($dark,.6),2.5), inset 0 -4px darken(rgba($dark,.6),4);
|
||||||
|
border-top-right-radius: $border-radius;
|
||||||
|
border-bottom-right-radius: $border-radius;
|
||||||
|
transition: all .2s ease;
|
||||||
|
z-index: 2;
|
||||||
|
|
||||||
|
.list-group-item {
|
||||||
|
background: transparent;
|
||||||
|
padding: 3px 0px;
|
||||||
|
color: $white;
|
||||||
|
border-color: rgba($black, 0.3);
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
padding-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tools-item {
|
||||||
|
.icon {
|
||||||
|
width: 22px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nitro-room-tools-info {
|
||||||
|
background: rgba($dark,.95);
|
||||||
|
box-shadow: inset 0px 5px lighten(rgba($dark,.6),2.5), inset 0 -4px darken(rgba($dark,.6),4);
|
||||||
|
transition: all .2s ease;
|
||||||
|
pointer-events: none;
|
||||||
|
max-width: 250px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.wordquiz-question {
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
font-size: large;
|
||||||
|
background: rgba($dark, 0.95);
|
||||||
|
box-shadow: inset 0px 5px lighten(rgba($dark,.6),2.5), inset 0 -4px darken(rgba($dark,.6),4);
|
||||||
|
border-radius: $border-radius;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
|
||||||
|
.question {
|
||||||
|
max-width: 300px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.word-quiz-dislike {
|
||||||
|
background: url("../../../assets/images/room-widgets/wordquiz-widget/thumbs-down.png");
|
||||||
|
width: 31px;
|
||||||
|
height: 34px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.word-quiz-like {
|
||||||
|
background: url("../../../assets/images/room-widgets/wordquiz-widget/thumbs-up.png");
|
||||||
|
width: 31px;
|
||||||
|
height: 34px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.word-quiz-dislike-sm {
|
||||||
|
background: url("../../../assets/images/room-widgets/wordquiz-widget/thumbs-down-small.png");
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.word-quiz-like-sm {
|
||||||
|
background: url("../../../assets/images/room-widgets/wordquiz-widget/thumbs-up-small.png");
|
||||||
|
height: 22px;
|
||||||
|
width: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
@import './avatar-info/AvatarInfoWidgetView';
|
@import './avatar-info/AvatarInfoWidgetView';
|
||||||
@import './chat/ChatWidgetView';
|
@import './chat/ChatWidgetView';
|
||||||
@import './chat-input/ChatInputView';
|
@import './chat-input/ChatInputView';
|
||||||
@import './choosers/ChooserWidgetView';
|
@import './choosers/ChooserWidgetView';
|
||||||
@import './context-menu/ContextMenu';
|
@import './context-menu/ContextMenu';
|
||||||
@import './doorbell/DoorbellWidgetView';
|
|
||||||
@import './friend-request/FriendRequestDialogView';
|
@import './friend-request/FriendRequestDialogView';
|
||||||
@import './furniture/FurnitureWidgets';
|
@import './furniture/FurnitureWidgets';
|
||||||
@import './infostand/InfoStandWidgetView';
|
@import './infostand/InfoStandWidgetView';
|
||||||
@import './object-location/ObjectLocationView';
|
|
||||||
@import './room-tools/RoomToolsWidgetView';
|
|
||||||
@import './word-quiz/WordQuizWidgetView';
|
|
||||||
|
@ -0,0 +1,71 @@
|
|||||||
|
import { BotSkillSaveComposer } from '@nitrots/nitro-renderer';
|
||||||
|
import { FC, useMemo, useState } from 'react';
|
||||||
|
import { GetRoomObjectBounds, GetRoomSession, LocalizeText, RoomWidgetUpdateRentableBotChatEvent } from '../../../../api';
|
||||||
|
import { Base, Button, Column, Flex, Text } from '../../../../common';
|
||||||
|
import { SendMessageHook } from '../../../../hooks';
|
||||||
|
import { DraggableWindow, DraggableWindowPosition } from '../../../../layout';
|
||||||
|
import { ContextMenuHeaderView } from '../context-menu/ContextMenuHeaderView';
|
||||||
|
import { BotSkillsEnum } from './common/BotSkillsEnum';
|
||||||
|
|
||||||
|
interface AvatarInfoRentableBotChatViewProps
|
||||||
|
{
|
||||||
|
chatEvent: RoomWidgetUpdateRentableBotChatEvent;
|
||||||
|
close(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AvatarInfoRentableBotChatView: FC<AvatarInfoRentableBotChatViewProps> = props =>
|
||||||
|
{
|
||||||
|
const { chatEvent = null, close = null } = props;
|
||||||
|
// eslint-disable-next-line no-template-curly-in-string
|
||||||
|
const [ newText, setNewText ] = useState<string>(chatEvent.chat === '${bot.skill.chatter.configuration.text.placeholder}' ? '' : chatEvent.chat);
|
||||||
|
const [ automaticChat, setAutomaticChat ] = useState<boolean>(chatEvent.automaticChat);
|
||||||
|
const [ mixSentences, setMixSentences ] = useState<boolean>(chatEvent.mixSentences);
|
||||||
|
const [ chatDelay, setChatDelay ] = useState<number>(chatEvent.chatDelay);
|
||||||
|
|
||||||
|
const getObjectLocation = useMemo(() => GetRoomObjectBounds(GetRoomSession().roomId, chatEvent.objectId, chatEvent.category, 1), [ chatEvent ]);
|
||||||
|
|
||||||
|
const formatChatString = (value: string) => value.replace(/;#;/g, ' ').replace(/\r\n|\r|\n/g, '\r');
|
||||||
|
|
||||||
|
const save = () =>
|
||||||
|
{
|
||||||
|
const chatConfiguration = formatChatString(newText) + ';#;' + automaticChat + ';#;' + chatDelay + ';#;' + mixSentences;
|
||||||
|
|
||||||
|
SendMessageHook(new BotSkillSaveComposer(chatEvent.botId, BotSkillsEnum.SETUP_CHAT, chatConfiguration));
|
||||||
|
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DraggableWindow position={ DraggableWindowPosition.NOTHING } handleSelector=".drag-handler" style={ { top: getObjectLocation.y, left: getObjectLocation.x } }>
|
||||||
|
<Base className="nitro-context-menu bot-chat">
|
||||||
|
<ContextMenuHeaderView className="drag-handler">
|
||||||
|
{ LocalizeText('bot.skill.chatter.configuration.title') }
|
||||||
|
</ContextMenuHeaderView>
|
||||||
|
<Column className="p-1">
|
||||||
|
<Column gap={ 1 }>
|
||||||
|
<Text variant="white">{ LocalizeText('bot.skill.chatter.configuration.chat.text') }</Text>
|
||||||
|
<textarea className="form-control form-control-sm" placeholder={LocalizeText('bot.skill.chatter.configuration.text.placeholder')} value={newText} rows={7} onChange={e => setNewText(e.target.value)} />
|
||||||
|
</Column>
|
||||||
|
<Column gap={ 1 }>
|
||||||
|
<Flex gap={ 1 } alignItems="center" justifyContent="between">
|
||||||
|
<Text fullWidth variant="white">{ LocalizeText('bot.skill.chatter.configuration.automatic.chat') }</Text>
|
||||||
|
<input type="checkbox" className="form-check-input" checked={ automaticChat } onChange={ event => setAutomaticChat(event.target.checked) } />
|
||||||
|
</Flex>
|
||||||
|
<Flex gap={ 1 } alignItems="center" justifyContent="between">
|
||||||
|
<Text fullWidth variant="white">{ LocalizeText('bot.skill.chatter.configuration.markov') }</Text>
|
||||||
|
<input type="checkbox" className="form-check-input" checked={ mixSentences } onChange={ event => setMixSentences(event.target.checked) } />
|
||||||
|
</Flex>
|
||||||
|
<Flex gap={ 1 } alignItems="center" justifyContent="between">
|
||||||
|
<Text fullWidth variant="white">{ LocalizeText('bot.skill.chatter.configuration.chat.delay') }</Text>
|
||||||
|
<input type="number" className="form-control form-control-sm" value={ chatDelay } onChange={ event => setChatDelay(event.target.valueAsNumber) }/>
|
||||||
|
</Flex>
|
||||||
|
</Column>
|
||||||
|
<Flex alignItems="center" justifyContent="between" gap={ 1 }>
|
||||||
|
<Button fullWidth variant="primary" onClick={ close }>{ LocalizeText('cancel') }</Button>
|
||||||
|
<Button fullWidth variant="success" onClick={ save }>{ LocalizeText('save') }</Button>
|
||||||
|
</Flex>
|
||||||
|
</Column>
|
||||||
|
</Base>
|
||||||
|
</DraggableWindow>
|
||||||
|
);
|
||||||
|
}
|
@ -1,11 +1,17 @@
|
|||||||
import { IFurnitureData, PetCustomPart, PetFigureData, RoomObjectCategory, RoomObjectVariable, RoomUserData } from '@nitrots/nitro-renderer';
|
import { IFurnitureData, PetCustomPart, PetFigureData, RoomObjectCategory, RoomObjectVariable, RoomUserData } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import { GetFurnitureDataForRoomObject, GetRoomEngine, LocalizeText, RoomWidgetUseProductMessage } from '../../../../../../api';
|
import { GetFurnitureDataForRoomObject, GetRoomEngine, LocalizeText, RoomWidgetUseProductMessage, UseProductItem } from '../../../../api';
|
||||||
import { FurniCategory } from '../../../../../../components/inventory/common/FurniCategory';
|
import { Base, Button, Column, Flex, Text } from '../../../../common';
|
||||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../../layout';
|
import { FurniCategory } from '../../../../components/inventory/common/FurniCategory';
|
||||||
import { PetImageView } from '../../../../../shared/pet-image/PetImageView';
|
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout';
|
||||||
import { useRoomContext } from '../../../../context/RoomContext';
|
import { PetImageView } from '../../../shared/pet-image/PetImageView';
|
||||||
import { AvatarInfoUseProductConfirmViewProps } from './AvatarInfoUseProductConfirmView.types';
|
import { useRoomContext } from '../../context/RoomContext';
|
||||||
|
|
||||||
|
interface AvatarInfoUseProductConfirmViewProps
|
||||||
|
{
|
||||||
|
item: UseProductItem;
|
||||||
|
close: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
const _Str_5091: number = -1;
|
const _Str_5091: number = -1;
|
||||||
const _Str_11906: number = 0;
|
const _Str_11906: number = 0;
|
||||||
@ -221,57 +227,57 @@ export const AvatarInfoUseProductConfirmView: FC<AvatarInfoUseProductConfirmView
|
|||||||
return (
|
return (
|
||||||
<NitroCardView className="nitro-use-product-confirmation">
|
<NitroCardView className="nitro-use-product-confirmation">
|
||||||
<NitroCardHeaderView headerText={ LocalizeText('useproduct.widget.title', [ 'name' ], [ petData.name ]) } onCloseClick={ close } />
|
<NitroCardHeaderView headerText={ LocalizeText('useproduct.widget.title', [ 'name' ], [ petData.name ]) } onCloseClick={ close } />
|
||||||
<NitroCardContentView>
|
<NitroCardContentView center>
|
||||||
<div className="row">
|
<Flex gap={ 2 } overflow="hidden">
|
||||||
<div className="w-unset">
|
<Column>
|
||||||
<div className="product-preview cursor-pointer" onClick={ selectRoomObject }>
|
<Base pointer className="product-preview" onClick={ selectRoomObject }>
|
||||||
{ getPetImage }
|
{ getPetImage }
|
||||||
</div>
|
</Base>
|
||||||
</div>
|
</Column>
|
||||||
<div className="col d-flex flex-column justify-content-between">
|
<Column justifyContent="between" overflow="auto">
|
||||||
<div className="d-flex flex-column">
|
<Column gap={ 2 }>
|
||||||
{ (mode === _Str_11906) &&
|
{ (mode === _Str_11906) &&
|
||||||
<>
|
<>
|
||||||
<div className="text-black mb-2">{ LocalizeText('useproduct.widget.text.shampoo', [ 'productName' ], [ furniData.name ] ) }</div>
|
<Text>{ LocalizeText('useproduct.widget.text.shampoo', [ 'productName' ], [ furniData.name ] ) }</Text>
|
||||||
<div className="text-black">{ LocalizeText('useproduct.widget.info.shampoo') }</div>
|
<Text>{ LocalizeText('useproduct.widget.info.shampoo') }</Text>
|
||||||
</> }
|
</> }
|
||||||
{ (mode === _Str_11214) &&
|
{ (mode === _Str_11214) &&
|
||||||
<>
|
<>
|
||||||
<div className="text-black mb-2">{ LocalizeText('useproduct.widget.text.custompart', [ 'productName' ], [ furniData.name ] ) }</div>
|
<Text>{ LocalizeText('useproduct.widget.text.custompart', [ 'productName' ], [ furniData.name ] ) }</Text>
|
||||||
<div className="text-black">{ LocalizeText('useproduct.widget.info.custompart') }</div>
|
<Text>{ LocalizeText('useproduct.widget.info.custompart') }</Text>
|
||||||
</> }
|
</> }
|
||||||
{ (mode === _Str_11733) &&
|
{ (mode === _Str_11733) &&
|
||||||
<>
|
<>
|
||||||
<div className="text-black mb-2">{ LocalizeText('useproduct.widget.text.custompartshampoo', [ 'productName' ], [ furniData.name ] ) }</div>
|
<Text>{ LocalizeText('useproduct.widget.text.custompartshampoo', [ 'productName' ], [ furniData.name ] ) }</Text>
|
||||||
<div className="text-black">{ LocalizeText('useproduct.widget.info.custompartshampoo') }</div>
|
<Text>{ LocalizeText('useproduct.widget.info.custompartshampoo') }</Text>
|
||||||
</> }
|
</> }
|
||||||
{ (mode === _Str_11369) &&
|
{ (mode === _Str_11369) &&
|
||||||
<>
|
<>
|
||||||
<div className="text-black mb-2">{ LocalizeText('useproduct.widget.text.saddle', [ 'productName' ], [ furniData.name ] ) }</div>
|
<Text>{ LocalizeText('useproduct.widget.text.saddle', [ 'productName' ], [ furniData.name ] ) }</Text>
|
||||||
<div className="text-black">{ LocalizeText('useproduct.widget.info.saddle') }</div>
|
<Text>{ LocalizeText('useproduct.widget.info.saddle') }</Text>
|
||||||
</> }
|
</> }
|
||||||
{ (mode === _Str_8759) &&
|
{ (mode === _Str_8759) &&
|
||||||
<>
|
<>
|
||||||
<div className="text-black mb-2">{ LocalizeText('useproduct.widget.text.revive_monsterplant', [ 'productName' ], [ furniData.name ] ) }</div>
|
<Text>{ LocalizeText('useproduct.widget.text.revive_monsterplant', [ 'productName' ], [ furniData.name ] ) }</Text>
|
||||||
<div className="text-black">{ LocalizeText('useproduct.widget.info.revive_monsterplant') }</div>
|
<Text>{ LocalizeText('useproduct.widget.info.revive_monsterplant') }</Text>
|
||||||
</> }
|
</> }
|
||||||
{ (mode === _Str_8432) &&
|
{ (mode === _Str_8432) &&
|
||||||
<>
|
<>
|
||||||
<div className="text-black mb-2">{ LocalizeText('useproduct.widget.text.rebreed_monsterplant', [ 'productName' ], [ furniData.name ] ) }</div>
|
<Text>{ LocalizeText('useproduct.widget.text.rebreed_monsterplant', [ 'productName' ], [ furniData.name ] ) }</Text>
|
||||||
<div className="text-black">{ LocalizeText('useproduct.widget.info.rebreed_monsterplant') }</div>
|
<Text>{ LocalizeText('useproduct.widget.info.rebreed_monsterplant') }</Text>
|
||||||
</> }
|
</> }
|
||||||
{ (mode === _Str_9653) &&
|
{ (mode === _Str_9653) &&
|
||||||
<>
|
<>
|
||||||
<div className="text-black mb-2">{ LocalizeText('useproduct.widget.text.fertilize_monsterplant', [ 'productName' ], [ furniData.name ] ) }</div>
|
<Text>{ LocalizeText('useproduct.widget.text.fertilize_monsterplant', [ 'productName' ], [ furniData.name ] ) }</Text>
|
||||||
<div className="text-black">{ LocalizeText('useproduct.widget.info.fertilize_monsterplant') }</div>
|
<Text>{ LocalizeText('useproduct.widget.info.fertilize_monsterplant') }</Text>
|
||||||
</> }
|
</> }
|
||||||
</div>
|
</Column>
|
||||||
<div className="d-flex justify-content-between align-items-end w-100 h-100">
|
<Flex alignItems="center" justifyContent="between">
|
||||||
<button type="button" className="btn btn-danger" onClick={ close }>{ LocalizeText('useproduct.widget.cancel') }</button>
|
<Button variant="danger" onClick={ close }>{ LocalizeText('useproduct.widget.cancel') }</Button>
|
||||||
<button type="button" className="btn btn-primary" onClick={ useProduct }>{ LocalizeText('useproduct.widget.use') }</button>
|
<Button variant="success" onClick={ useProduct }>{ LocalizeText('useproduct.widget.use') }</Button>
|
||||||
</div>
|
</Flex>
|
||||||
</div>
|
</Column>
|
||||||
</div>
|
</Flex>
|
||||||
</NitroCardContentView>
|
</NitroCardContentView>
|
||||||
</NitroCardView>
|
</NitroCardView>
|
||||||
)
|
)
|
@ -1,12 +1,18 @@
|
|||||||
import { RoomObjectCategory, RoomObjectType } from '@nitrots/nitro-renderer';
|
import { RoomObjectCategory, RoomObjectType } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback, useEffect, useState } from 'react';
|
import { FC, useCallback, useEffect, useState } from 'react';
|
||||||
import { GetFurnitureDataForRoomObject, LocalizeText } from '../../../../../../api';
|
import { GetFurnitureDataForRoomObject, LocalizeText, UseProductItem } from '../../../../api';
|
||||||
import { FurniCategory } from '../../../../../../components/inventory/common/FurniCategory';
|
import { FurniCategory } from '../../../../components/inventory/common/FurniCategory';
|
||||||
import { useRoomContext } from '../../../../context/RoomContext';
|
import { useRoomContext } from '../../context/RoomContext';
|
||||||
import { ContextMenuView } from '../../../context-menu/ContextMenuView';
|
import { ContextMenuHeaderView } from '../context-menu/ContextMenuHeaderView';
|
||||||
import { ContextMenuHeaderView } from '../../../context-menu/views/header/ContextMenuHeaderView';
|
import { ContextMenuListItemView } from '../context-menu/ContextMenuListItemView';
|
||||||
import { ContextMenuListItemView } from '../../../context-menu/views/list-item/ContextMenuListItemView';
|
import { ContextMenuView } from '../context-menu/ContextMenuView';
|
||||||
import { AvatarInfoUseProductViewProps } from './AvatarInfoUseProductView.types';
|
|
||||||
|
interface AvatarInfoUseProductViewProps
|
||||||
|
{
|
||||||
|
item: UseProductItem;
|
||||||
|
updateConfirmingProduct: (product: UseProductItem) => void;
|
||||||
|
close: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
const PRODUCT_PAGE_UKNOWN: number = 0;
|
const PRODUCT_PAGE_UKNOWN: number = 0;
|
||||||
const PRODUCT_PAGE_SHAMPOO: number = 1;
|
const PRODUCT_PAGE_SHAMPOO: number = 1;
|
@ -1,11 +1,18 @@
|
|||||||
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import { RoomControllerLevel, RoomObjectCategory, RoomObjectVariable } from '@nitrots/nitro-renderer';
|
import { RoomControllerLevel, RoomObjectCategory, RoomObjectVariable } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
import { FC, useEffect, useMemo, useState } from 'react';
|
||||||
import { GetOwnRoomObject, GetUserProfile, LocalizeText, RoomWidgetMessage, RoomWidgetUserActionMessage } from '../../../../../../api';
|
import { GetOwnRoomObject, GetUserProfile, LocalizeText, RoomWidgetMessage, RoomWidgetUpdateInfostandUserEvent, RoomWidgetUserActionMessage } from '../../../../api';
|
||||||
import { useRoomContext } from '../../../../context/RoomContext';
|
import { BatchUpdates } from '../../../../hooks';
|
||||||
import { ContextMenuView } from '../../../context-menu/ContextMenuView';
|
import { useRoomContext } from '../../context/RoomContext';
|
||||||
import { ContextMenuHeaderView } from '../../../context-menu/views/header/ContextMenuHeaderView';
|
import { ContextMenuHeaderView } from '../context-menu/ContextMenuHeaderView';
|
||||||
import { ContextMenuListItemView } from '../../../context-menu/views/list-item/ContextMenuListItemView';
|
import { ContextMenuListItemView } from '../context-menu/ContextMenuListItemView';
|
||||||
import { AvatarInfoWidgetAvatarViewProps } from './AvatarInfoWidgetAvatarView.types';
|
import { ContextMenuView } from '../context-menu/ContextMenuView';
|
||||||
|
|
||||||
|
interface AvatarInfoWidgetAvatarViewProps
|
||||||
|
{
|
||||||
|
userData: RoomWidgetUpdateInfostandUserEvent;
|
||||||
|
close: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
const MODE_NORMAL = 0;
|
const MODE_NORMAL = 0;
|
||||||
const MODE_MODERATE = 1;
|
const MODE_MODERATE = 1;
|
||||||
@ -21,12 +28,6 @@ export const AvatarInfoWidgetAvatarView: FC<AvatarInfoWidgetAvatarViewProps> = p
|
|||||||
const [ respectsLeft, setRespectsLeft ] = useState(0);
|
const [ respectsLeft, setRespectsLeft ] = useState(0);
|
||||||
const { widgetHandler = null } = useRoomContext();
|
const { widgetHandler = null } = useRoomContext();
|
||||||
|
|
||||||
useEffect(() =>
|
|
||||||
{
|
|
||||||
setMode(MODE_NORMAL);
|
|
||||||
setRespectsLeft(userData.respectLeft);
|
|
||||||
}, [ userData ])
|
|
||||||
|
|
||||||
const isShowGiveRights = useMemo(() =>
|
const isShowGiveRights = useMemo(() =>
|
||||||
{
|
{
|
||||||
return (userData.amIOwner && (userData.targetRoomControllerLevel < RoomControllerLevel.GUEST) && !userData.isGuildRoom);
|
return (userData.amIOwner && (userData.targetRoomControllerLevel < RoomControllerLevel.GUEST) && !userData.isGuildRoom);
|
||||||
@ -42,7 +43,23 @@ export const AvatarInfoWidgetAvatarView: FC<AvatarInfoWidgetAvatarViewProps> = p
|
|||||||
return (userData.canBeKicked || userData.canBeBanned || userData.canBeMuted || isShowGiveRights || isShowRemoveRights);
|
return (userData.canBeKicked || userData.canBeBanned || userData.canBeMuted || isShowGiveRights || isShowRemoveRights);
|
||||||
}, [ isShowGiveRights, isShowRemoveRights, userData ]);
|
}, [ isShowGiveRights, isShowRemoveRights, userData ]);
|
||||||
|
|
||||||
const processAction = useCallback((name: string) =>
|
const canGiveHandItem = useMemo(() =>
|
||||||
|
{
|
||||||
|
let flag = false;
|
||||||
|
|
||||||
|
const roomObject = GetOwnRoomObject();
|
||||||
|
|
||||||
|
if(roomObject)
|
||||||
|
{
|
||||||
|
const carryId = roomObject.model.getValue<number>(RoomObjectVariable.FIGURE_CARRY_OBJECT);
|
||||||
|
|
||||||
|
if((carryId > 0) && (carryId < 999999)) flag = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return flag;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const processAction = (name: string) =>
|
||||||
{
|
{
|
||||||
let messageType: string = null;
|
let messageType: string = null;
|
||||||
let message: RoomWidgetMessage = null;
|
let message: RoomWidgetMessage = null;
|
||||||
@ -173,23 +190,16 @@ export const AvatarInfoWidgetAvatarView: FC<AvatarInfoWidgetAvatarViewProps> = p
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(hideMenu) close();
|
if(hideMenu) close();
|
||||||
}, [ widgetHandler, userData, close ]);
|
|
||||||
|
|
||||||
const canGiveHandItem = useMemo(() =>
|
|
||||||
{
|
|
||||||
let flag = false;
|
|
||||||
|
|
||||||
const roomObject = GetOwnRoomObject();
|
|
||||||
|
|
||||||
if(roomObject)
|
|
||||||
{
|
|
||||||
const carryId = roomObject.model.getValue<number>(RoomObjectVariable.FIGURE_CARRY_OBJECT);
|
|
||||||
|
|
||||||
if((carryId > 0) && (carryId < 999999)) flag = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return flag;
|
useEffect(() =>
|
||||||
}, []);
|
{
|
||||||
|
BatchUpdates(() =>
|
||||||
|
{
|
||||||
|
setMode(MODE_NORMAL);
|
||||||
|
setRespectsLeft(userData.respectLeft);
|
||||||
|
});
|
||||||
|
}, [ userData ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ContextMenuView objectId={ userData.roomIndex } category={ RoomObjectCategory.UNIT } userType={ userData.userType } close={ close }>
|
<ContextMenuView objectId={ userData.roomIndex } category={ RoomObjectCategory.UNIT } userType={ userData.userType } close={ close }>
|
||||||
@ -225,12 +235,12 @@ export const AvatarInfoWidgetAvatarView: FC<AvatarInfoWidgetAvatarViewProps> = p
|
|||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
{ moderateMenuHasContent &&
|
{ moderateMenuHasContent &&
|
||||||
<ContextMenuListItemView onClick={ event => processAction('moderate') }>
|
<ContextMenuListItemView onClick={ event => processAction('moderate') }>
|
||||||
<i className="fas fa-chevron-right right" />
|
<FontAwesomeIcon icon="chevron-right" className="right" />
|
||||||
{ LocalizeText('infostand.link.moderate') }
|
{ LocalizeText('infostand.link.moderate') }
|
||||||
</ContextMenuListItemView> }
|
</ContextMenuListItemView> }
|
||||||
{ userData.isAmbassador &&
|
{ userData.isAmbassador &&
|
||||||
<ContextMenuListItemView onClick={ event => processAction('ambassador') }>
|
<ContextMenuListItemView onClick={ event => processAction('ambassador') }>
|
||||||
<i className="fas fa-chevron-right right" />
|
<FontAwesomeIcon icon="chevron-right" className="right" />
|
||||||
{ LocalizeText('infostand.link.ambassador') }
|
{ LocalizeText('infostand.link.ambassador') }
|
||||||
</ContextMenuListItemView> }
|
</ContextMenuListItemView> }
|
||||||
{ canGiveHandItem && <ContextMenuListItemView onClick={ event => processAction('pass_hand_item') }>
|
{ canGiveHandItem && <ContextMenuListItemView onClick={ event => processAction('pass_hand_item') }>
|
||||||
@ -243,11 +253,11 @@ export const AvatarInfoWidgetAvatarView: FC<AvatarInfoWidgetAvatarViewProps> = p
|
|||||||
{ LocalizeText('infostand.button.kick') }
|
{ LocalizeText('infostand.button.kick') }
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
<ContextMenuListItemView onClick={ event => processAction('mute') }>
|
<ContextMenuListItemView onClick={ event => processAction('mute') }>
|
||||||
<i className="fas fa-chevron-right right" />
|
<FontAwesomeIcon icon="chevron-right" className="right" />
|
||||||
{ LocalizeText('infostand.button.mute') }
|
{ LocalizeText('infostand.button.mute') }
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
<ContextMenuListItemView onClick={ event => processAction('ban') }>
|
<ContextMenuListItemView onClick={ event => processAction('ban') }>
|
||||||
<i className="fas fa-chevron-right right" />
|
<FontAwesomeIcon icon="chevron-right" className="right" />
|
||||||
{ LocalizeText('infostand.button.ban') }
|
{ LocalizeText('infostand.button.ban') }
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
{ isShowGiveRights &&
|
{ isShowGiveRights &&
|
||||||
@ -259,7 +269,7 @@ export const AvatarInfoWidgetAvatarView: FC<AvatarInfoWidgetAvatarViewProps> = p
|
|||||||
{ LocalizeText('infostand.button.removerights') }
|
{ LocalizeText('infostand.button.removerights') }
|
||||||
</ContextMenuListItemView> }
|
</ContextMenuListItemView> }
|
||||||
<ContextMenuListItemView onClick={ event => processAction('back') }>
|
<ContextMenuListItemView onClick={ event => processAction('back') }>
|
||||||
<i className="fas fa-chevron-left left" />
|
<FontAwesomeIcon icon="chevron-left" className="left" />
|
||||||
{ LocalizeText('generic.back') }
|
{ LocalizeText('generic.back') }
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
</> }
|
</> }
|
||||||
@ -275,7 +285,7 @@ export const AvatarInfoWidgetAvatarView: FC<AvatarInfoWidgetAvatarViewProps> = p
|
|||||||
{ LocalizeText('infostand.button.perm_ban') }
|
{ LocalizeText('infostand.button.perm_ban') }
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
<ContextMenuListItemView onClick={ event => processAction('back_moderate') }>
|
<ContextMenuListItemView onClick={ event => processAction('back_moderate') }>
|
||||||
<i className="fas fa-chevron-left left" />
|
<FontAwesomeIcon icon="chevron-left" className="left" />
|
||||||
{ LocalizeText('generic.back') }
|
{ LocalizeText('generic.back') }
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
</> }
|
</> }
|
||||||
@ -291,7 +301,7 @@ export const AvatarInfoWidgetAvatarView: FC<AvatarInfoWidgetAvatarViewProps> = p
|
|||||||
{ LocalizeText('infostand.button.mute_10min') }
|
{ LocalizeText('infostand.button.mute_10min') }
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
<ContextMenuListItemView onClick={ event => processAction('back_moderate') }>
|
<ContextMenuListItemView onClick={ event => processAction('back_moderate') }>
|
||||||
<i className="fas fa-chevron-left left" />
|
<FontAwesomeIcon icon="chevron-left" className="left" />
|
||||||
{ LocalizeText('generic.back') }
|
{ LocalizeText('generic.back') }
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
</> }
|
</> }
|
||||||
@ -304,11 +314,11 @@ export const AvatarInfoWidgetAvatarView: FC<AvatarInfoWidgetAvatarViewProps> = p
|
|||||||
{ LocalizeText('infostand.button.kick') }
|
{ LocalizeText('infostand.button.kick') }
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
<ContextMenuListItemView onClick={ event => processAction('ambassador_mute') }>
|
<ContextMenuListItemView onClick={ event => processAction('ambassador_mute') }>
|
||||||
<i className="fas fa-chevron-right right" />
|
|
||||||
{ LocalizeText('infostand.button.mute') }
|
{ LocalizeText('infostand.button.mute') }
|
||||||
|
<FontAwesomeIcon icon="chevron-right" className="right" />
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
<ContextMenuListItemView onClick={ event => processAction('back') }>
|
<ContextMenuListItemView onClick={ event => processAction('back') }>
|
||||||
<i className="fas fa-chevron-left left" />
|
<FontAwesomeIcon icon="chevron-left" className="left" />
|
||||||
{ LocalizeText('generic.back') }
|
{ LocalizeText('generic.back') }
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
</> }
|
</> }
|
||||||
@ -327,7 +337,7 @@ export const AvatarInfoWidgetAvatarView: FC<AvatarInfoWidgetAvatarViewProps> = p
|
|||||||
{ LocalizeText('infostand.button.mute_18hour') }
|
{ LocalizeText('infostand.button.mute_18hour') }
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
<ContextMenuListItemView onClick={ event => processAction('back_ambassador') }>
|
<ContextMenuListItemView onClick={ event => processAction('back_ambassador') }>
|
||||||
<i className="fas fa-chevron-left left" />
|
<FontAwesomeIcon icon="chevron-left" className="left" />
|
||||||
{ LocalizeText('generic.back') }
|
{ LocalizeText('generic.back') }
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
</> }
|
</> }
|
@ -1,21 +1,24 @@
|
|||||||
import { RoomObjectCategory } from '@nitrots/nitro-renderer';
|
import { RoomObjectCategory } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback } from 'react';
|
import { FC } from 'react';
|
||||||
import { LocalizeText, RoomWidgetUpdateDecorateModeEvent } from '../../../../../../api';
|
import { LocalizeText, RoomWidgetUpdateDecorateModeEvent } from '../../../../api';
|
||||||
import { useRoomContext } from '../../../../context/RoomContext';
|
import { useRoomContext } from '../../context/RoomContext';
|
||||||
import { ContextMenuView } from '../../../context-menu/ContextMenuView';
|
import { ContextMenuListItemView } from '../context-menu/ContextMenuListItemView';
|
||||||
import { ContextMenuListItemView } from '../../../context-menu/views/list-item/ContextMenuListItemView';
|
import { ContextMenuListView } from '../context-menu/ContextMenuListView';
|
||||||
import { ContextMenuListView } from '../../../context-menu/views/list/ContextMenuListView';
|
import { ContextMenuView } from '../context-menu/ContextMenuView';
|
||||||
import { AvatarInfoWidgetDecorateViewProps } from './AvatarInfoWidgetDecorateView.types';
|
|
||||||
|
interface AvatarInfoWidgetDecorateViewProps
|
||||||
|
{
|
||||||
|
userId: number;
|
||||||
|
userName: string;
|
||||||
|
roomIndex: number;
|
||||||
|
}
|
||||||
|
|
||||||
export const AvatarInfoWidgetDecorateView: FC<AvatarInfoWidgetDecorateViewProps> = props =>
|
export const AvatarInfoWidgetDecorateView: FC<AvatarInfoWidgetDecorateViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { userId = -1, userName = '', roomIndex = -1 } = props;
|
const { userId = -1, userName = '', roomIndex = -1 } = props;
|
||||||
const { eventDispatcher = null } = useRoomContext();
|
const { eventDispatcher = null } = useRoomContext();
|
||||||
|
|
||||||
const stopDecorating = useCallback(() =>
|
const stopDecorating = () => eventDispatcher.dispatchEvent(new RoomWidgetUpdateDecorateModeEvent(false));
|
||||||
{
|
|
||||||
eventDispatcher.dispatchEvent(new RoomWidgetUpdateDecorateModeEvent(false));
|
|
||||||
}, [ eventDispatcher ]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ContextMenuView objectId={ roomIndex } category={ RoomObjectCategory.UNIT } close={ null }>
|
<ContextMenuView objectId={ roomIndex } category={ RoomObjectCategory.UNIT } close={ null }>
|
@ -1,16 +1,18 @@
|
|||||||
import { FC, useMemo } from 'react';
|
import { FC, useMemo } from 'react';
|
||||||
import { GetSessionDataManager } from '../../../../../../api';
|
import { GetSessionDataManager, RoomWidgetObjectNameEvent } from '../../../../api';
|
||||||
import { ContextMenuView } from '../../../context-menu/ContextMenuView';
|
import { ContextMenuView } from '../context-menu/ContextMenuView';
|
||||||
import { AvatarInfoWidgetNameViewProps } from './AvatarInfoWidgetNameView.types';
|
|
||||||
|
interface AvatarInfoWidgetNameViewProps
|
||||||
|
{
|
||||||
|
nameData: RoomWidgetObjectNameEvent;
|
||||||
|
close: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
export const AvatarInfoWidgetNameView: FC<AvatarInfoWidgetNameViewProps> = props =>
|
export const AvatarInfoWidgetNameView: FC<AvatarInfoWidgetNameViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { nameData = null, close = null } = props;
|
const { nameData = null, close = null } = props;
|
||||||
|
|
||||||
const fades = useMemo(() =>
|
const fades = useMemo(() => (nameData.id !== GetSessionDataManager().userId), [ nameData ]);
|
||||||
{
|
|
||||||
return (nameData.id !== GetSessionDataManager().userId);
|
|
||||||
}, [ nameData ]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ContextMenuView objectId={ nameData.roomIndex } category={ nameData.category } userType={ nameData.userType } fades={ fades } className="name-only" close= { close }>
|
<ContextMenuView objectId={ nameData.roomIndex } category={ nameData.category } userType={ nameData.userType } fades={ fades } className="name-only" close= { close }>
|
@ -1,15 +1,23 @@
|
|||||||
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import { AvatarAction, AvatarExpressionEnum, RoomControllerLevel, RoomObjectCategory } from '@nitrots/nitro-renderer';
|
import { AvatarAction, AvatarExpressionEnum, RoomControllerLevel, RoomObjectCategory } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback, useMemo, useState } from 'react';
|
import { FC, useCallback, useMemo, useState } from 'react';
|
||||||
import { GetCanStandUp, GetCanUseExpression, GetOwnPosture, GetUserProfile, HasHabboClub, HasHabboVip, IsRidingHorse, LocalizeText, RoomWidgetAvatarExpressionMessage, RoomWidgetChangePostureMessage, RoomWidgetDanceMessage, RoomWidgetMessage, RoomWidgetUpdateDecorateModeEvent, RoomWidgetUserActionMessage } from '../../../../../../api';
|
import { GetCanStandUp, GetCanUseExpression, GetOwnPosture, GetUserProfile, HasHabboClub, HasHabboVip, IsRidingHorse, LocalizeText, RoomWidgetAvatarExpressionMessage, RoomWidgetChangePostureMessage, RoomWidgetDanceMessage, RoomWidgetMessage, RoomWidgetUpdateDecorateModeEvent, RoomWidgetUpdateInfostandUserEvent, RoomWidgetUserActionMessage } from '../../../../api';
|
||||||
import { AvatarEditorEvent } from '../../../../../../events';
|
import { Flex } from '../../../../common';
|
||||||
import { HelpNameChangeEvent } from '../../../../../../events/help/HelpNameChangeEvent';
|
import { AvatarEditorEvent } from '../../../../events';
|
||||||
import { dispatchUiEvent } from '../../../../../../hooks';
|
import { HelpNameChangeEvent } from '../../../../events/help/HelpNameChangeEvent';
|
||||||
import { CurrencyIcon } from '../../../../../shared/currency-icon/CurrencyIcon';
|
import { dispatchUiEvent } from '../../../../hooks';
|
||||||
import { useRoomContext } from '../../../../context/RoomContext';
|
import { CurrencyIcon } from '../../../shared/currency-icon/CurrencyIcon';
|
||||||
import { ContextMenuView } from '../../../context-menu/ContextMenuView';
|
import { useRoomContext } from '../../context/RoomContext';
|
||||||
import { ContextMenuHeaderView } from '../../../context-menu/views/header/ContextMenuHeaderView';
|
import { ContextMenuHeaderView } from '../context-menu/ContextMenuHeaderView';
|
||||||
import { ContextMenuListItemView } from '../../../context-menu/views/list-item/ContextMenuListItemView';
|
import { ContextMenuListItemView } from '../context-menu/ContextMenuListItemView';
|
||||||
import { AvatarInfoWidgetOwnAvatarViewProps } from './AvatarInfoWidgetOwnAvatarView.types';
|
import { ContextMenuView } from '../context-menu/ContextMenuView';
|
||||||
|
|
||||||
|
interface AvatarInfoWidgetOwnAvatarViewProps
|
||||||
|
{
|
||||||
|
userData: RoomWidgetUpdateInfostandUserEvent;
|
||||||
|
isDancing: boolean;
|
||||||
|
close: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
const MODE_NORMAL = 0;
|
const MODE_NORMAL = 0;
|
||||||
const MODE_CLUB_DANCES = 1;
|
const MODE_CLUB_DANCES = 1;
|
||||||
@ -134,7 +142,7 @@ export const AvatarInfoWidgetOwnAvatarView: FC<AvatarInfoWidgetOwnAvatarViewProp
|
|||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
{ (HasHabboClub() && !isRidingHorse) &&
|
{ (HasHabboClub() && !isRidingHorse) &&
|
||||||
<ContextMenuListItemView onClick={ event => processAction('dance_menu') }>
|
<ContextMenuListItemView onClick={ event => processAction('dance_menu') }>
|
||||||
<i className="fas fa-chevron-right right" />
|
<FontAwesomeIcon icon="chevron-right" className="right" />
|
||||||
{ LocalizeText('widget.memenu.dance') }
|
{ LocalizeText('widget.memenu.dance') }
|
||||||
</ContextMenuListItemView> }
|
</ContextMenuListItemView> }
|
||||||
{ (!isDancing && !HasHabboClub() && !isRidingHorse) &&
|
{ (!isDancing && !HasHabboClub() && !isRidingHorse) &&
|
||||||
@ -146,11 +154,11 @@ export const AvatarInfoWidgetOwnAvatarView: FC<AvatarInfoWidgetOwnAvatarViewProp
|
|||||||
{ LocalizeText('widget.memenu.dance.stop') }
|
{ LocalizeText('widget.memenu.dance.stop') }
|
||||||
</ContextMenuListItemView> }
|
</ContextMenuListItemView> }
|
||||||
<ContextMenuListItemView onClick={ event => processAction('expressions') }>
|
<ContextMenuListItemView onClick={ event => processAction('expressions') }>
|
||||||
<i className="fas fa-chevron-right right" />
|
<FontAwesomeIcon icon="chevron-right" className="right" />
|
||||||
{ LocalizeText('infostand.link.expressions') }
|
{ LocalizeText('infostand.link.expressions') }
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
<ContextMenuListItemView onClick={ event => processAction('signs') }>
|
<ContextMenuListItemView onClick={ event => processAction('signs') }>
|
||||||
<i className="fas fa-chevron-right right" />
|
<FontAwesomeIcon icon="chevron-right" className="right" />
|
||||||
{ LocalizeText('infostand.show.signs') }
|
{ LocalizeText('infostand.show.signs') }
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
{ (userData.carryItem > 0) &&
|
{ (userData.carryItem > 0) &&
|
||||||
@ -177,7 +185,7 @@ export const AvatarInfoWidgetOwnAvatarView: FC<AvatarInfoWidgetOwnAvatarViewProp
|
|||||||
{ LocalizeText('widget.memenu.dance4') }
|
{ LocalizeText('widget.memenu.dance4') }
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
<ContextMenuListItemView onClick={ event => processAction('back') }>
|
<ContextMenuListItemView onClick={ event => processAction('back') }>
|
||||||
<i className="fas fa-chevron-left left" />
|
<FontAwesomeIcon icon="chevron-left" className="left" />
|
||||||
{ LocalizeText('generic.back') }
|
{ LocalizeText('generic.back') }
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
</> }
|
</> }
|
||||||
@ -196,12 +204,12 @@ export const AvatarInfoWidgetOwnAvatarView: FC<AvatarInfoWidgetOwnAvatarViewProp
|
|||||||
{ LocalizeText('widget.memenu.wave') }
|
{ LocalizeText('widget.memenu.wave') }
|
||||||
</ContextMenuListItemView> }
|
</ContextMenuListItemView> }
|
||||||
{ GetCanUseExpression() &&
|
{ GetCanUseExpression() &&
|
||||||
<ContextMenuListItemView canSelect={ HasHabboVip() } onClick={ event => processAction('laugh') }>
|
<ContextMenuListItemView disabled={ !HasHabboVip() } onClick={ event => processAction('laugh') }>
|
||||||
<CurrencyIcon type="hc" />
|
<CurrencyIcon type="hc" />
|
||||||
{ LocalizeText('widget.memenu.laugh') }
|
{ LocalizeText('widget.memenu.laugh') }
|
||||||
</ContextMenuListItemView> }
|
</ContextMenuListItemView> }
|
||||||
{ GetCanUseExpression() &&
|
{ GetCanUseExpression() &&
|
||||||
<ContextMenuListItemView canSelect={ HasHabboVip() } onClick={ event => processAction('blow') }>
|
<ContextMenuListItemView disabled={ !HasHabboVip() } onClick={ event => processAction('blow') }>
|
||||||
<CurrencyIcon type="hc" />
|
<CurrencyIcon type="hc" />
|
||||||
{ LocalizeText('widget.memenu.blow') }
|
{ LocalizeText('widget.memenu.blow') }
|
||||||
</ContextMenuListItemView> }
|
</ContextMenuListItemView> }
|
||||||
@ -209,13 +217,13 @@ export const AvatarInfoWidgetOwnAvatarView: FC<AvatarInfoWidgetOwnAvatarViewProp
|
|||||||
{ LocalizeText('widget.memenu.idle') }
|
{ LocalizeText('widget.memenu.idle') }
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
<ContextMenuListItemView onClick={ event => processAction('back') }>
|
<ContextMenuListItemView onClick={ event => processAction('back') }>
|
||||||
<i className="fas fa-chevron-left left" />
|
<FontAwesomeIcon icon="chevron-left" className="left" />
|
||||||
{ LocalizeText('generic.back') }
|
{ LocalizeText('generic.back') }
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
</> }
|
</> }
|
||||||
{ (mode === MODE_SIGNS) &&
|
{ (mode === MODE_SIGNS) &&
|
||||||
<>
|
<>
|
||||||
<div className="d-flex menu-list-split-3">
|
<Flex className="menu-list-split-3">
|
||||||
<ContextMenuListItemView onClick={ event => processAction('sign_1') }>
|
<ContextMenuListItemView onClick={ event => processAction('sign_1') }>
|
||||||
1
|
1
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
@ -225,8 +233,8 @@ export const AvatarInfoWidgetOwnAvatarView: FC<AvatarInfoWidgetOwnAvatarViewProp
|
|||||||
<ContextMenuListItemView onClick={ event => processAction('sign_3') }>
|
<ContextMenuListItemView onClick={ event => processAction('sign_3') }>
|
||||||
3
|
3
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
</div>
|
</Flex>
|
||||||
<div className="d-flex menu-list-split-3">
|
<Flex className="menu-list-split-3">
|
||||||
<ContextMenuListItemView onClick={ event => processAction('sign_4') }>
|
<ContextMenuListItemView onClick={ event => processAction('sign_4') }>
|
||||||
4
|
4
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
@ -236,8 +244,8 @@ export const AvatarInfoWidgetOwnAvatarView: FC<AvatarInfoWidgetOwnAvatarViewProp
|
|||||||
<ContextMenuListItemView onClick={ event => processAction('sign_6') }>
|
<ContextMenuListItemView onClick={ event => processAction('sign_6') }>
|
||||||
6
|
6
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
</div>
|
</Flex>
|
||||||
<div className="d-flex menu-list-split-3">
|
<Flex className="menu-list-split-3">
|
||||||
<ContextMenuListItemView onClick={ event => processAction('sign_7') }>
|
<ContextMenuListItemView onClick={ event => processAction('sign_7') }>
|
||||||
7
|
7
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
@ -247,8 +255,8 @@ export const AvatarInfoWidgetOwnAvatarView: FC<AvatarInfoWidgetOwnAvatarViewProp
|
|||||||
<ContextMenuListItemView onClick={ event => processAction('sign_9') }>
|
<ContextMenuListItemView onClick={ event => processAction('sign_9') }>
|
||||||
9
|
9
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
</div>
|
</Flex>
|
||||||
<div className="d-flex menu-list-split-3">
|
<Flex className="menu-list-split-3">
|
||||||
<ContextMenuListItemView onClick={ event => processAction('sign_10') }>
|
<ContextMenuListItemView onClick={ event => processAction('sign_10') }>
|
||||||
10
|
10
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
@ -258,8 +266,8 @@ export const AvatarInfoWidgetOwnAvatarView: FC<AvatarInfoWidgetOwnAvatarViewProp
|
|||||||
<ContextMenuListItemView onClick={ event => processAction('sign_15') }>
|
<ContextMenuListItemView onClick={ event => processAction('sign_15') }>
|
||||||
<i className="icon icon-sign-smile" />
|
<i className="icon icon-sign-smile" />
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
</div>
|
</Flex>
|
||||||
<div className="d-flex menu-list-split-3">
|
<Flex className="menu-list-split-3">
|
||||||
<ContextMenuListItemView onClick={ event => processAction('sign_12') }>
|
<ContextMenuListItemView onClick={ event => processAction('sign_12') }>
|
||||||
<i className="icon icon-sign-skull" />
|
<i className="icon icon-sign-skull" />
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
@ -269,8 +277,8 @@ export const AvatarInfoWidgetOwnAvatarView: FC<AvatarInfoWidgetOwnAvatarViewProp
|
|||||||
<ContextMenuListItemView onClick={ event => processAction('sign_17') }>
|
<ContextMenuListItemView onClick={ event => processAction('sign_17') }>
|
||||||
<i className="icon icon-sign-yellow" />
|
<i className="icon icon-sign-yellow" />
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
</div>
|
</Flex>
|
||||||
<div className="d-flex menu-list-split-3">
|
<Flex className="menu-list-split-3">
|
||||||
<ContextMenuListItemView onClick={ event => processAction('sign_16') }>
|
<ContextMenuListItemView onClick={ event => processAction('sign_16') }>
|
||||||
<i className="icon icon-sign-red" />
|
<i className="icon icon-sign-red" />
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
@ -280,9 +288,9 @@ export const AvatarInfoWidgetOwnAvatarView: FC<AvatarInfoWidgetOwnAvatarViewProp
|
|||||||
<ContextMenuListItemView onClick={ event => processAction('sign_11') }>
|
<ContextMenuListItemView onClick={ event => processAction('sign_11') }>
|
||||||
<i className="icon icon-sign-heart" />
|
<i className="icon icon-sign-heart" />
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
</div>
|
</Flex>
|
||||||
<ContextMenuListItemView onClick={ event => processAction('back') }>
|
<ContextMenuListItemView onClick={ event => processAction('back') }>
|
||||||
<i className="fas fa-chevron-left left" />
|
<FontAwesomeIcon icon="chevron-left" className="left" />
|
||||||
{ LocalizeText('generic.back') }
|
{ LocalizeText('generic.back') }
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
</> }
|
</> }
|
@ -1,11 +1,17 @@
|
|||||||
import { PetType, RoomObjectCategory, RoomObjectType, RoomObjectVariable } from '@nitrots/nitro-renderer';
|
import { PetType, RoomObjectCategory, RoomObjectType, RoomObjectVariable } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
import { FC, useEffect, useMemo, useState } from 'react';
|
||||||
import { GetOwnRoomObject, LocalizeText, RoomWidgetMessage, RoomWidgetUserActionMessage } from '../../../../../../api';
|
import { GetOwnRoomObject, LocalizeText, RoomWidgetMessage, RoomWidgetUpdateInfostandPetEvent, RoomWidgetUserActionMessage } from '../../../../api';
|
||||||
import { useRoomContext } from '../../../../context/RoomContext';
|
import { BatchUpdates } from '../../../../hooks';
|
||||||
import { ContextMenuView } from '../../../context-menu/ContextMenuView';
|
import { useRoomContext } from '../../context/RoomContext';
|
||||||
import { ContextMenuHeaderView } from '../../../context-menu/views/header/ContextMenuHeaderView';
|
import { ContextMenuHeaderView } from '../context-menu/ContextMenuHeaderView';
|
||||||
import { ContextMenuListItemView } from '../../../context-menu/views/list-item/ContextMenuListItemView';
|
import { ContextMenuListItemView } from '../context-menu/ContextMenuListItemView';
|
||||||
import { AvatarInfoWidgetOwnPetViewProps } from './AvatarInfoWidgetOwnPetView.types';
|
import { ContextMenuView } from '../context-menu/ContextMenuView';
|
||||||
|
|
||||||
|
interface AvatarInfoWidgetOwnPetViewProps
|
||||||
|
{
|
||||||
|
petData: RoomWidgetUpdateInfostandPetEvent;
|
||||||
|
close: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
const _Str_2906: number = 0;
|
const _Str_2906: number = 0;
|
||||||
const _Str_5818: number = 1;
|
const _Str_5818: number = 1;
|
||||||
@ -19,21 +25,23 @@ export const AvatarInfoWidgetOwnPetView: FC<AvatarInfoWidgetOwnPetViewProps> = p
|
|||||||
const [ respectsLeft, setRespectsLeft ] = useState(0);
|
const [ respectsLeft, setRespectsLeft ] = useState(0);
|
||||||
const { roomSession = null, widgetHandler = null } = useRoomContext();
|
const { roomSession = null, widgetHandler = null } = useRoomContext();
|
||||||
|
|
||||||
useEffect(() =>
|
const canGiveHandItem = useMemo(() =>
|
||||||
{
|
{
|
||||||
setMode(prevValue =>
|
let flag = false;
|
||||||
|
|
||||||
|
const roomObject = GetOwnRoomObject();
|
||||||
|
|
||||||
|
if(roomObject)
|
||||||
{
|
{
|
||||||
if(petData.petType === PetType.MONSTERPLANT) return _Str_10946;
|
const carryId = roomObject.model.getValue<number>(RoomObjectVariable.FIGURE_CARRY_OBJECT);
|
||||||
else if(petData.saddle && !petData.rider) return _Str_5818;
|
|
||||||
else if(petData.rider) return _Str_5938;
|
|
||||||
|
|
||||||
return _Str_2906;
|
if((carryId > 0) && (carryId < 999999)) flag = true;
|
||||||
});
|
}
|
||||||
|
|
||||||
setRespectsLeft(petData.respectsPetLeft);
|
return flag;
|
||||||
}, [ petData ])
|
}, []);
|
||||||
|
|
||||||
const processAction = useCallback((name: string) =>
|
const processAction = (name: string) =>
|
||||||
{
|
{
|
||||||
let messageType: string = null;
|
let messageType: string = null;
|
||||||
let message: RoomWidgetMessage = null;
|
let message: RoomWidgetMessage = null;
|
||||||
@ -118,23 +126,24 @@ export const AvatarInfoWidgetOwnPetView: FC<AvatarInfoWidgetOwnPetViewProps> = p
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(hideMenu) close();
|
if(hideMenu) close();
|
||||||
}, [ widgetHandler, petData, mode, close ]);
|
|
||||||
|
|
||||||
const canGiveHandItem = useMemo(() =>
|
|
||||||
{
|
|
||||||
let flag = false;
|
|
||||||
|
|
||||||
const roomObject = GetOwnRoomObject();
|
|
||||||
|
|
||||||
if(roomObject)
|
|
||||||
{
|
|
||||||
const carryId = roomObject.model.getValue<number>(RoomObjectVariable.FIGURE_CARRY_OBJECT);
|
|
||||||
|
|
||||||
if((carryId > 0) && (carryId < 999999)) flag = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return flag;
|
useEffect(() =>
|
||||||
}, []);
|
{
|
||||||
|
BatchUpdates(() =>
|
||||||
|
{
|
||||||
|
setMode(prevValue =>
|
||||||
|
{
|
||||||
|
if(petData.petType === PetType.MONSTERPLANT) return _Str_10946;
|
||||||
|
else if(petData.saddle && !petData.rider) return _Str_5818;
|
||||||
|
else if(petData.rider) return _Str_5938;
|
||||||
|
|
||||||
|
return _Str_2906;
|
||||||
|
});
|
||||||
|
|
||||||
|
setRespectsLeft(petData.respectsPetLeft);
|
||||||
|
});
|
||||||
|
}, [ petData ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ContextMenuView objectId={ petData.roomIndex } category={ RoomObjectCategory.UNIT } userType={ RoomObjectType.PET } close={ close }>
|
<ContextMenuView objectId={ petData.roomIndex } category={ RoomObjectCategory.UNIT } userType={ RoomObjectType.PET } close={ close }>
|
||||||
@ -167,8 +176,8 @@ export const AvatarInfoWidgetOwnPetView: FC<AvatarInfoWidgetOwnPetViewProps> = p
|
|||||||
<ContextMenuListItemView onClick={ event => processAction('mount') }>
|
<ContextMenuListItemView onClick={ event => processAction('mount') }>
|
||||||
{ LocalizeText('infostand.button.mount') }
|
{ LocalizeText('infostand.button.mount') }
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
<ContextMenuListItemView onClick={ event => processAction('toggle_riding_permission') }>
|
<ContextMenuListItemView onClick={ event => processAction('toggle_riding_permission') } gap={ 1 }>
|
||||||
<input type="checkbox" className="me-1" checked={ !!petData.publiclyRideable } readOnly={ true } />
|
<input type="checkbox" checked={ !!petData.publiclyRideable } readOnly={ true } />
|
||||||
{ LocalizeText('infostand.button.toggle_riding_permission') }
|
{ LocalizeText('infostand.button.toggle_riding_permission') }
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
{ (respectsLeft > 0) &&
|
{ (respectsLeft > 0) &&
|
||||||
@ -214,8 +223,8 @@ export const AvatarInfoWidgetOwnPetView: FC<AvatarInfoWidgetOwnPetViewProps> = p
|
|||||||
</ContextMenuListItemView> }
|
</ContextMenuListItemView> }
|
||||||
{ !petData.dead && (petData.level === petData.maximumLevel) && petData.breedable &&
|
{ !petData.dead && (petData.level === petData.maximumLevel) && petData.breedable &&
|
||||||
<>
|
<>
|
||||||
<ContextMenuListItemView onClick={ event => processAction('toggle_breeding_permission') }>
|
<ContextMenuListItemView onClick={ event => processAction('toggle_breeding_permission') } gap={ 1 }>
|
||||||
<input type="checkbox" className="me-1" checked={ petData.publiclyBreedable } readOnly={ true } />
|
<input type="checkbox" checked={ petData.publiclyBreedable } readOnly={ true } />
|
||||||
{ LocalizeText('infostand.button.toggle_breeding_permission') }
|
{ LocalizeText('infostand.button.toggle_breeding_permission') }
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
<ContextMenuListItemView onClick={ event => processAction('breed') }>
|
<ContextMenuListItemView onClick={ event => processAction('breed') }>
|
@ -1,11 +1,17 @@
|
|||||||
import { PetType, RoomControllerLevel, RoomObjectCategory, RoomObjectType, RoomObjectVariable } from '@nitrots/nitro-renderer';
|
import { PetType, RoomControllerLevel, RoomObjectCategory, RoomObjectType, RoomObjectVariable } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
import { FC, useEffect, useMemo, useState } from 'react';
|
||||||
import { GetOwnRoomObject, GetSessionDataManager, LocalizeText, RoomWidgetMessage, RoomWidgetUserActionMessage } from '../../../../../../api';
|
import { GetOwnRoomObject, GetSessionDataManager, LocalizeText, RoomWidgetMessage, RoomWidgetUpdateInfostandPetEvent, RoomWidgetUserActionMessage } from '../../../../api';
|
||||||
import { useRoomContext } from '../../../../context/RoomContext';
|
import { BatchUpdates } from '../../../../hooks';
|
||||||
import { ContextMenuView } from '../../../context-menu/ContextMenuView';
|
import { useRoomContext } from '../../context/RoomContext';
|
||||||
import { ContextMenuHeaderView } from '../../../context-menu/views/header/ContextMenuHeaderView';
|
import { ContextMenuHeaderView } from '../context-menu/ContextMenuHeaderView';
|
||||||
import { ContextMenuListItemView } from '../../../context-menu/views/list-item/ContextMenuListItemView';
|
import { ContextMenuListItemView } from '../context-menu/ContextMenuListItemView';
|
||||||
import { AvatarInfoWidgetPetViewProps } from './AvatarInfoWidgetPetView.types';
|
import { ContextMenuView } from '../context-menu/ContextMenuView';
|
||||||
|
|
||||||
|
interface AvatarInfoWidgetPetViewProps
|
||||||
|
{
|
||||||
|
petData: RoomWidgetUpdateInfostandPetEvent;
|
||||||
|
close: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
const _Str_2906: number = 0;
|
const _Str_2906: number = 0;
|
||||||
const _Str_5818: number = 1;
|
const _Str_5818: number = 1;
|
||||||
@ -19,21 +25,28 @@ export const AvatarInfoWidgetPetView: FC<AvatarInfoWidgetPetViewProps> = props =
|
|||||||
const [ respectsLeft, setRespectsLeft ] = useState(0);
|
const [ respectsLeft, setRespectsLeft ] = useState(0);
|
||||||
const { roomSession = null, widgetHandler = null } = useRoomContext();
|
const { roomSession = null, widgetHandler = null } = useRoomContext();
|
||||||
|
|
||||||
useEffect(() =>
|
const canPickUp = useMemo(() =>
|
||||||
{
|
{
|
||||||
setMode(prevValue =>
|
return (roomSession.isRoomOwner || (roomSession.controllerLevel >= RoomControllerLevel.GUEST) || GetSessionDataManager().isModerator);
|
||||||
|
}, [ roomSession ]);
|
||||||
|
|
||||||
|
const canGiveHandItem = useMemo(() =>
|
||||||
{
|
{
|
||||||
if(petData.petType === PetType.MONSTERPLANT) return _Str_13388;
|
let flag = false;
|
||||||
else if(petData.saddle && !petData.rider) return _Str_5818;
|
|
||||||
else if(petData.rider) return _Str_5938;
|
|
||||||
|
|
||||||
return _Str_2906;
|
const roomObject = GetOwnRoomObject();
|
||||||
});
|
|
||||||
|
|
||||||
setRespectsLeft(petData.respectsPetLeft);
|
if(roomObject)
|
||||||
}, [ petData ])
|
{
|
||||||
|
const carryId = roomObject.model.getValue<number>(RoomObjectVariable.FIGURE_CARRY_OBJECT);
|
||||||
|
|
||||||
const processAction = useCallback((name: string) =>
|
if((carryId > 0) && (carryId < 999999)) flag = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return flag;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const processAction = (name: string) =>
|
||||||
{
|
{
|
||||||
let messageType: string = null;
|
let messageType: string = null;
|
||||||
let message: RoomWidgetMessage = null;
|
let message: RoomWidgetMessage = null;
|
||||||
@ -80,28 +93,24 @@ export const AvatarInfoWidgetPetView: FC<AvatarInfoWidgetPetViewProps> = props =
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(hideMenu) close();
|
if(hideMenu) close();
|
||||||
}, [ widgetHandler, petData, close ]);
|
|
||||||
|
|
||||||
const canPickUp = useMemo(() =>
|
|
||||||
{
|
|
||||||
return (roomSession.isRoomOwner || (roomSession.controllerLevel >= RoomControllerLevel.GUEST) || GetSessionDataManager().isModerator);
|
|
||||||
}, [ roomSession ]);
|
|
||||||
|
|
||||||
const canGiveHandItem = useMemo(() =>
|
|
||||||
{
|
|
||||||
let flag = false;
|
|
||||||
|
|
||||||
const roomObject = GetOwnRoomObject();
|
|
||||||
|
|
||||||
if(roomObject)
|
|
||||||
{
|
|
||||||
const carryId = roomObject.model.getValue<number>(RoomObjectVariable.FIGURE_CARRY_OBJECT);
|
|
||||||
|
|
||||||
if((carryId > 0) && (carryId < 999999)) flag = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return flag;
|
useEffect(() =>
|
||||||
}, []);
|
{
|
||||||
|
BatchUpdates(() =>
|
||||||
|
{
|
||||||
|
setMode(prevValue =>
|
||||||
|
{
|
||||||
|
if(petData.petType === PetType.MONSTERPLANT) return _Str_13388;
|
||||||
|
else if(petData.saddle && !petData.rider) return _Str_5818;
|
||||||
|
else if(petData.rider) return _Str_5938;
|
||||||
|
|
||||||
|
return _Str_2906;
|
||||||
|
});
|
||||||
|
|
||||||
|
setRespectsLeft(petData.respectsPetLeft);
|
||||||
|
});
|
||||||
|
}, [ petData ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ContextMenuView objectId={ petData.roomIndex } category={ RoomObjectCategory.UNIT } userType={ RoomObjectType.PET } close={ close }>
|
<ContextMenuView objectId={ petData.roomIndex } category={ RoomObjectCategory.UNIT } userType={ RoomObjectType.PET } close={ close }>
|
@ -1,13 +1,19 @@
|
|||||||
import { BotCommandConfigurationEvent, BotRemoveComposer, BotSkillSaveComposer, RequestBotCommandConfigurationComposer, RoomObjectCategory, RoomObjectType } from '@nitrots/nitro-renderer';
|
import { BotCommandConfigurationEvent, BotRemoveComposer, BotSkillSaveComposer, RequestBotCommandConfigurationComposer, RoomObjectCategory, RoomObjectType } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback, useEffect, useState } from 'react';
|
import { FC, useCallback, useEffect, useState } from 'react';
|
||||||
import { GetNitroInstance, LocalizeText, RoomWidgetUpdateRentableBotChatEvent } from '../../../../../../api';
|
import { GetNitroInstance, LocalizeText, RoomWidgetUpdateInfostandRentableBotEvent, RoomWidgetUpdateRentableBotChatEvent } from '../../../../api';
|
||||||
import { CreateMessageHook, SendMessageHook } from '../../../../../../hooks/messages';
|
import { Button, Column, Flex, Text } from '../../../../common';
|
||||||
import { useRoomContext } from '../../../../context/RoomContext';
|
import { CreateMessageHook, SendMessageHook } from '../../../../hooks/messages';
|
||||||
import { ContextMenuView } from '../../../context-menu/ContextMenuView';
|
import { useRoomContext } from '../../context/RoomContext';
|
||||||
import { ContextMenuHeaderView } from '../../../context-menu/views/header/ContextMenuHeaderView';
|
import { ContextMenuHeaderView } from '../context-menu/ContextMenuHeaderView';
|
||||||
import { ContextMenuListItemView } from '../../../context-menu/views/list-item/ContextMenuListItemView';
|
import { ContextMenuListItemView } from '../context-menu/ContextMenuListItemView';
|
||||||
import { BotSkillsEnum } from '../../common/BotSkillsEnum';
|
import { ContextMenuView } from '../context-menu/ContextMenuView';
|
||||||
import { AvatarInfoWidgetRentableBotViewProps } from './AvatarInfoWidgetRentableBotView.types';
|
import { BotSkillsEnum } from './common/BotSkillsEnum';
|
||||||
|
|
||||||
|
interface AvatarInfoWidgetRentableBotViewProps
|
||||||
|
{
|
||||||
|
rentableBotData: RoomWidgetUpdateInfostandRentableBotEvent;
|
||||||
|
close: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
const MODE_NORMAL = 0;
|
const MODE_NORMAL = 0;
|
||||||
const MODE_CHANGE_NAME = 1;
|
const MODE_CHANGE_NAME = 1;
|
||||||
@ -21,17 +27,10 @@ export const AvatarInfoWidgetRentableBotView: FC<AvatarInfoWidgetRentableBotView
|
|||||||
const [ newMotto, setNewMotto ] = useState('');
|
const [ newMotto, setNewMotto ] = useState('');
|
||||||
const { eventDispatcher = null } = useRoomContext();
|
const { eventDispatcher = null } = useRoomContext();
|
||||||
|
|
||||||
useEffect(() =>
|
|
||||||
{
|
|
||||||
setMode(MODE_NORMAL);
|
|
||||||
}, [ rentableBotData ]);
|
|
||||||
|
|
||||||
const onBotCommandConfigurationEvent = useCallback((event: BotCommandConfigurationEvent) =>
|
const onBotCommandConfigurationEvent = useCallback((event: BotCommandConfigurationEvent) =>
|
||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
|
|
||||||
if(!parser) return;
|
|
||||||
|
|
||||||
if(parser.botId !== rentableBotData.webID) return;
|
if(parser.botId !== rentableBotData.webID) return;
|
||||||
|
|
||||||
switch(parser.commandId)
|
switch(parser.commandId)
|
||||||
@ -69,12 +68,9 @@ export const AvatarInfoWidgetRentableBotView: FC<AvatarInfoWidgetRentableBotView
|
|||||||
|
|
||||||
CreateMessageHook(BotCommandConfigurationEvent, onBotCommandConfigurationEvent);
|
CreateMessageHook(BotCommandConfigurationEvent, onBotCommandConfigurationEvent);
|
||||||
|
|
||||||
const requestBotCommandConfiguration = useCallback((skillType: number) =>
|
const requestBotCommandConfiguration = (skillType: number) => SendMessageHook(new RequestBotCommandConfigurationComposer(rentableBotData.webID, skillType));
|
||||||
{
|
|
||||||
SendMessageHook(new RequestBotCommandConfigurationComposer(rentableBotData.webID, skillType));
|
|
||||||
}, [ rentableBotData ]);
|
|
||||||
|
|
||||||
const processAction = useCallback((name: string) =>
|
const processAction = (name: string) =>
|
||||||
{
|
{
|
||||||
let hideMenu = true;
|
let hideMenu = true;
|
||||||
|
|
||||||
@ -130,7 +126,12 @@ export const AvatarInfoWidgetRentableBotView: FC<AvatarInfoWidgetRentableBotView
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(hideMenu) close();
|
if(hideMenu) close();
|
||||||
}, [ rentableBotData, newName, newMotto, requestBotCommandConfiguration, close ]);
|
}
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
setMode(MODE_NORMAL);
|
||||||
|
}, [ rentableBotData ]);
|
||||||
|
|
||||||
const canControl = (rentableBotData.amIOwner || rentableBotData.amIAnyRoomController);
|
const canControl = (rentableBotData.amIOwner || rentableBotData.amIAnyRoomController);
|
||||||
|
|
||||||
@ -139,63 +140,63 @@ export const AvatarInfoWidgetRentableBotView: FC<AvatarInfoWidgetRentableBotView
|
|||||||
<ContextMenuHeaderView>
|
<ContextMenuHeaderView>
|
||||||
{ rentableBotData.name }
|
{ rentableBotData.name }
|
||||||
</ContextMenuHeaderView>
|
</ContextMenuHeaderView>
|
||||||
{ (mode === MODE_NORMAL) &&
|
{ (mode === MODE_NORMAL) && canControl &&
|
||||||
<>
|
<>
|
||||||
{ ((rentableBotData.botSkills.indexOf(BotSkillsEnum.DONATE_TO_ALL) >= 0) && canControl) &&
|
{ (rentableBotData.botSkills.indexOf(BotSkillsEnum.DONATE_TO_ALL) >= 0) &&
|
||||||
<ContextMenuListItemView onClick={ event => processAction('donate_to_all') }>
|
<ContextMenuListItemView onClick={ event => processAction('donate_to_all') }>
|
||||||
{ LocalizeText('avatar.widget.donate_to_all') }
|
{ LocalizeText('avatar.widget.donate_to_all') }
|
||||||
</ContextMenuListItemView> }
|
</ContextMenuListItemView> }
|
||||||
{ ((rentableBotData.botSkills.indexOf(BotSkillsEnum.DONATE_TO_USER) >= 0) && canControl) &&
|
{ (rentableBotData.botSkills.indexOf(BotSkillsEnum.DONATE_TO_USER) >= 0) &&
|
||||||
<ContextMenuListItemView onClick={ event => processAction('donate_to_user') }>
|
<ContextMenuListItemView onClick={ event => processAction('donate_to_user') }>
|
||||||
{ LocalizeText('avatar.widget.donate_to_user') }
|
{ LocalizeText('avatar.widget.donate_to_user') }
|
||||||
</ContextMenuListItemView> }
|
</ContextMenuListItemView> }
|
||||||
{ ((rentableBotData.botSkills.indexOf(BotSkillsEnum.CHANGE_BOT_NAME) >= 0) && canControl) &&
|
{ (rentableBotData.botSkills.indexOf(BotSkillsEnum.CHANGE_BOT_NAME) >= 0) &&
|
||||||
<ContextMenuListItemView onClick={ event => processAction('change_bot_name') }>
|
<ContextMenuListItemView onClick={ event => processAction('change_bot_name') }>
|
||||||
{ LocalizeText('avatar.widget.change_bot_name') }
|
{ LocalizeText('avatar.widget.change_bot_name') }
|
||||||
</ContextMenuListItemView> }
|
</ContextMenuListItemView> }
|
||||||
{ ((rentableBotData.botSkills.indexOf(BotSkillsEnum.CHANGE_BOT_MOTTO) >= 0) && canControl) &&
|
{ (rentableBotData.botSkills.indexOf(BotSkillsEnum.CHANGE_BOT_MOTTO) >= 0) &&
|
||||||
<ContextMenuListItemView onClick={ event => processAction('change_bot_motto') }>
|
<ContextMenuListItemView onClick={ event => processAction('change_bot_motto') }>
|
||||||
{ LocalizeText('avatar.widget.change_bot_motto') }
|
{ LocalizeText('avatar.widget.change_bot_motto') }
|
||||||
</ContextMenuListItemView> }
|
</ContextMenuListItemView> }
|
||||||
{ ((rentableBotData.botSkills.indexOf(BotSkillsEnum.DRESS_UP) >= 0) && canControl) &&
|
{ (rentableBotData.botSkills.indexOf(BotSkillsEnum.DRESS_UP) >= 0) &&
|
||||||
<ContextMenuListItemView onClick={ event => processAction('dress_up') }>
|
<ContextMenuListItemView onClick={ event => processAction('dress_up') }>
|
||||||
{ LocalizeText('avatar.widget.dress_up') }
|
{ LocalizeText('avatar.widget.dress_up') }
|
||||||
</ContextMenuListItemView> }
|
</ContextMenuListItemView> }
|
||||||
{ ((rentableBotData.botSkills.indexOf(BotSkillsEnum.RANDOM_WALK) >= 0) && canControl) &&
|
{ (rentableBotData.botSkills.indexOf(BotSkillsEnum.RANDOM_WALK) >= 0) &&
|
||||||
<ContextMenuListItemView onClick={ event => processAction('random_walk') }>
|
<ContextMenuListItemView onClick={ event => processAction('random_walk') }>
|
||||||
{ LocalizeText('avatar.widget.random_walk') }
|
{ LocalizeText('avatar.widget.random_walk') }
|
||||||
</ContextMenuListItemView> }
|
</ContextMenuListItemView> }
|
||||||
{ ((rentableBotData.botSkills.indexOf(BotSkillsEnum.SETUP_CHAT) >= 0) && canControl) &&
|
{ (rentableBotData.botSkills.indexOf(BotSkillsEnum.SETUP_CHAT) >= 0) &&
|
||||||
<ContextMenuListItemView onClick={ event => processAction('setup_chat') }>
|
<ContextMenuListItemView onClick={ event => processAction('setup_chat') }>
|
||||||
{ LocalizeText('avatar.widget.setup_chat') }
|
{ LocalizeText('avatar.widget.setup_chat') }
|
||||||
</ContextMenuListItemView> }
|
</ContextMenuListItemView> }
|
||||||
{ ((rentableBotData.botSkills.indexOf(BotSkillsEnum.DANCE) >= 0) && canControl) &&
|
{ (rentableBotData.botSkills.indexOf(BotSkillsEnum.DANCE) >= 0) &&
|
||||||
<ContextMenuListItemView onClick={ event => processAction('dance') }>
|
<ContextMenuListItemView onClick={ event => processAction('dance') }>
|
||||||
{ LocalizeText('avatar.widget.dance') }
|
{ LocalizeText('avatar.widget.dance') }
|
||||||
</ContextMenuListItemView> }
|
</ContextMenuListItemView> }
|
||||||
{ ((rentableBotData.botSkills.indexOf(BotSkillsEnum.NO_PICK_UP) === -1) && canControl) &&
|
{ (rentableBotData.botSkills.indexOf(BotSkillsEnum.NO_PICK_UP) === -1) &&
|
||||||
<ContextMenuListItemView onClick={ event => processAction('pick') }>
|
<ContextMenuListItemView onClick={ event => processAction('pick') }>
|
||||||
{ LocalizeText('avatar.widget.pick_up') }
|
{ LocalizeText('avatar.widget.pick_up') }
|
||||||
</ContextMenuListItemView> }
|
</ContextMenuListItemView> }
|
||||||
</> }
|
</> }
|
||||||
{ (mode === MODE_CHANGE_NAME) &&
|
{ (mode === MODE_CHANGE_NAME) &&
|
||||||
<div className="d-flex flex-column menu-item" onClick={ null }>
|
<Column className="menu-item" onClick={ null } gap={ 1 }>
|
||||||
<p className="mb-1">{ LocalizeText('bot.skill.name.configuration.new.name') }</p>
|
<Text variant="white">{ LocalizeText('bot.skill.name.configuration.new.name') }</Text>
|
||||||
<input type="text" className="form-control form-control-sm mb-2" value={ newName } onChange={ event => setNewName(event.target.value) } />
|
<input type="text" className="form-control form-control-sm" value={ newName } onChange={ event => setNewName(event.target.value) } />
|
||||||
<div className="d-flex justify-content-between align-items-center">
|
<Flex alignItems="center" justifyContent="between" gap={ 1 }>
|
||||||
<button type="button" className="btn btn-secondary btn-sm" onClick={ event => processAction(null) }>{ LocalizeText('cancel') }</button>
|
<Button fullWidth variant="secondary" onClick={ event => processAction(null) }>{ LocalizeText('cancel') }</Button>
|
||||||
<button type="button" className="btn btn-success btn-sm" onClick={ event => processAction('save_bot_name') }>{ LocalizeText('save') }</button>
|
<Button fullWidth variant="success" onClick={ event => processAction('save_bot_name') }>{ LocalizeText('save') }</Button>
|
||||||
</div>
|
</Flex>
|
||||||
</div> }
|
</Column> }
|
||||||
{ (mode === MODE_CHANGE_MOTTO) &&
|
{ (mode === MODE_CHANGE_MOTTO) &&
|
||||||
<div className="d-flex flex-column menu-item" onClick={ null }>
|
<Column className="menu-item" onClick={ null } gap={ 1 }>
|
||||||
<p className="mb-1">{ LocalizeText('bot.skill.name.configuration.new.motto') }</p>
|
<Text variant="white">{ LocalizeText('bot.skill.name.configuration.new.motto') }</Text>
|
||||||
<input type="text" className="form-control form-control-sm mb-2" value={ newMotto } onChange={ event => setNewMotto(event.target.value) } />
|
<input type="text" className="form-control form-control-sm" value={ newMotto } onChange={ event => setNewMotto(event.target.value) } />
|
||||||
<div className="d-flex justify-content-between align-items-center">
|
<Flex alignItems="center" justifyContent="between" gap={ 1 }>
|
||||||
<button type="button" className="btn btn-secondary btn-sm" onClick={ event => processAction(null) }>{ LocalizeText('cancel') }</button>
|
<Button fullWidth variant="secondary" onClick={ event => processAction(null) }>{ LocalizeText('cancel') }</Button>
|
||||||
<button type="button" className="btn btn-success btn-sm" onClick={ event => processAction('save_bot_motto') }>{ LocalizeText('save') }</button>
|
<Button fullWidth variant="success" onClick={ event => processAction('save_bot_motto') }>{ LocalizeText('save') }</Button>
|
||||||
</div>
|
</Flex>
|
||||||
</div> }
|
</Column> }
|
||||||
</ContextMenuView>
|
</ContextMenuView>
|
||||||
);
|
);
|
||||||
}
|
}
|
@ -20,14 +20,4 @@
|
|||||||
background: url('../../../../assets/images/room-widgets/furni-context-menu/monsterplant-preview.png') no-repeat center;
|
background: url('../../../../assets/images/room-widgets/furni-context-menu/monsterplant-preview.png') no-repeat center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mannequin-preview {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
width: 83px;
|
|
||||||
height: 130px;
|
|
||||||
background-image: url('../../../../assets/images/room-widgets/mannequin-widget/mannequin-spritesheet.png');
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -3,16 +3,16 @@ import { FC, useCallback, useMemo, useState } from 'react';
|
|||||||
import { GetRoomSession, GetSessionDataManager, RoomWidgetObjectNameEvent, RoomWidgetRoomObjectMessage, RoomWidgetUpdateDanceStatusEvent, RoomWidgetUpdateDecorateModeEvent, RoomWidgetUpdateInfostandEvent, RoomWidgetUpdateInfostandFurniEvent, RoomWidgetUpdateInfostandPetEvent, RoomWidgetUpdateInfostandRentableBotEvent, RoomWidgetUpdateInfostandUserEvent, RoomWidgetUpdateRentableBotChatEvent, RoomWidgetUpdateRoomEngineEvent, RoomWidgetUpdateRoomObjectEvent, RoomWidgetUseProductBubbleEvent, UseProductItem } from '../../../../api';
|
import { GetRoomSession, GetSessionDataManager, RoomWidgetObjectNameEvent, RoomWidgetRoomObjectMessage, RoomWidgetUpdateDanceStatusEvent, RoomWidgetUpdateDecorateModeEvent, RoomWidgetUpdateInfostandEvent, RoomWidgetUpdateInfostandFurniEvent, RoomWidgetUpdateInfostandPetEvent, RoomWidgetUpdateInfostandRentableBotEvent, RoomWidgetUpdateInfostandUserEvent, RoomWidgetUpdateRentableBotChatEvent, RoomWidgetUpdateRoomEngineEvent, RoomWidgetUpdateRoomObjectEvent, RoomWidgetUseProductBubbleEvent, UseProductItem } from '../../../../api';
|
||||||
import { CreateEventDispatcherHook } from '../../../../hooks/events/event-dispatcher.base';
|
import { CreateEventDispatcherHook } from '../../../../hooks/events/event-dispatcher.base';
|
||||||
import { useRoomContext } from '../../context/RoomContext';
|
import { useRoomContext } from '../../context/RoomContext';
|
||||||
import { AvatarInfoWidgetAvatarView } from './views/avatar/AvatarInfoWidgetAvatarView';
|
import { AvatarInfoRentableBotChatView } from './AvatarInfoRentableBotChatView';
|
||||||
import { AvatarInfoWidgetDecorateView } from './views/decorate/AvatarInfoWidgetDecorateView';
|
import { AvatarInfoUseProductConfirmView } from './AvatarInfoUseProductConfirmView';
|
||||||
import { AvatarInfoWidgetNameView } from './views/name/AvatarInfoWidgetNameView';
|
import { AvatarInfoUseProductView } from './AvatarInfoUseProductView';
|
||||||
import { AvatarInfoWidgetOwnAvatarView } from './views/own-avatar/AvatarInfoWidgetOwnAvatarView';
|
import { AvatarInfoWidgetAvatarView } from './AvatarInfoWidgetAvatarView';
|
||||||
import { AvatarInfoWidgetOwnPetView } from './views/own-pet/AvatarInfoWidgetOwnPetView';
|
import { AvatarInfoWidgetDecorateView } from './AvatarInfoWidgetDecorateView';
|
||||||
import { AvatarInfoWidgetPetView } from './views/pet/AvatarInfoWidgetPetView';
|
import { AvatarInfoWidgetNameView } from './AvatarInfoWidgetNameView';
|
||||||
import { AvatarInfoRentableBotChatView } from './views/rentable-bot-chat/AvatarInfoRentableBotChatView';
|
import { AvatarInfoWidgetOwnAvatarView } from './AvatarInfoWidgetOwnAvatarView';
|
||||||
import { AvatarInfoWidgetRentableBotView } from './views/rentable-bot/AvatarInfoWidgetRentableBotView';
|
import { AvatarInfoWidgetOwnPetView } from './AvatarInfoWidgetOwnPetView';
|
||||||
import { AvatarInfoUseProductConfirmView } from './views/use-product-confirm/AvatarInfoUseProductConfirmView';
|
import { AvatarInfoWidgetPetView } from './AvatarInfoWidgetPetView';
|
||||||
import { AvatarInfoUseProductView } from './views/use-product/AvatarInfoUseProductView';
|
import { AvatarInfoWidgetRentableBotView } from './AvatarInfoWidgetRentableBotView';
|
||||||
|
|
||||||
export const AvatarInfoWidgetView: FC<{}> = props =>
|
export const AvatarInfoWidgetView: FC<{}> = props =>
|
||||||
{
|
{
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
import { RoomWidgetUpdateInfostandUserEvent } from '../../../../../../api';
|
|
||||||
|
|
||||||
export interface AvatarInfoWidgetAvatarViewProps
|
|
||||||
{
|
|
||||||
userData: RoomWidgetUpdateInfostandUserEvent;
|
|
||||||
close: () => void;
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
|
|
||||||
export interface AvatarInfoWidgetDecorateViewProps
|
|
||||||
{
|
|
||||||
userId: number;
|
|
||||||
userName: string;
|
|
||||||
roomIndex: number;
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
import { RoomWidgetObjectNameEvent } from '../../../../../../api';
|
|
||||||
|
|
||||||
export interface AvatarInfoWidgetNameViewProps
|
|
||||||
{
|
|
||||||
nameData: RoomWidgetObjectNameEvent;
|
|
||||||
close: () => void;
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
import { RoomWidgetUpdateInfostandUserEvent } from '../../../../../../api';
|
|
||||||
|
|
||||||
export interface AvatarInfoWidgetOwnAvatarViewProps
|
|
||||||
{
|
|
||||||
userData: RoomWidgetUpdateInfostandUserEvent;
|
|
||||||
isDancing: boolean;
|
|
||||||
close: () => void;
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
import { RoomWidgetUpdateInfostandPetEvent } from '../../../../../../api';
|
|
||||||
|
|
||||||
export interface AvatarInfoWidgetOwnPetViewProps
|
|
||||||
{
|
|
||||||
petData: RoomWidgetUpdateInfostandPetEvent;
|
|
||||||
close: () => void;
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
import { RoomWidgetUpdateInfostandPetEvent } from '../../../../../../api';
|
|
||||||
|
|
||||||
export interface AvatarInfoWidgetPetViewProps
|
|
||||||
{
|
|
||||||
petData: RoomWidgetUpdateInfostandPetEvent;
|
|
||||||
close: () => void;
|
|
||||||
}
|
|
@ -1,65 +0,0 @@
|
|||||||
import { BotSkillSaveComposer } from '@nitrots/nitro-renderer';
|
|
||||||
import { FC, useCallback, useMemo, useState } from 'react';
|
|
||||||
import { GetRoomObjectBounds, GetRoomSession, LocalizeText } from '../../../../../../api';
|
|
||||||
import { SendMessageHook } from '../../../../../../hooks';
|
|
||||||
import { DraggableWindow, DraggableWindowPosition } from '../../../../../../layout';
|
|
||||||
import { BotSkillsEnum } from '../../common/BotSkillsEnum';
|
|
||||||
import { AvatarInfoRentableBotChatViewProps } from './AvatarInfoRentableBotChatView.types';
|
|
||||||
|
|
||||||
export const AvatarInfoRentableBotChatView: FC<AvatarInfoRentableBotChatViewProps> = props =>
|
|
||||||
{
|
|
||||||
const { chatEvent = null, close = null } = props;
|
|
||||||
// eslint-disable-next-line no-template-curly-in-string
|
|
||||||
const [ newText, setNewText ] = useState<string>(chatEvent.chat === '${bot.skill.chatter.configuration.text.placeholder}' ? '' : chatEvent.chat);
|
|
||||||
const [ automaticChat, setAutomaticChat ] = useState<boolean>(chatEvent.automaticChat);
|
|
||||||
const [ mixSentences, setMixSentences ] = useState<boolean>(chatEvent.mixSentences);
|
|
||||||
const [ chatDelay, setChatDelay ] = useState<number>(chatEvent.chatDelay);
|
|
||||||
|
|
||||||
const getObjectLocation = useMemo(() =>
|
|
||||||
{
|
|
||||||
return GetRoomObjectBounds(GetRoomSession().roomId, chatEvent.objectId, chatEvent.category, 1);
|
|
||||||
}, [ chatEvent ]);
|
|
||||||
|
|
||||||
const formatChatString = useCallback((value: string) =>
|
|
||||||
{
|
|
||||||
return value.replace(/;#;/g, ' ').replace(/\r\n|\r|\n/g, '\r');
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const save = useCallback(() =>
|
|
||||||
{
|
|
||||||
const chatConfiguration = formatChatString(newText) + ';#;' + automaticChat + ';#;' + chatDelay + ';#;' + mixSentences;
|
|
||||||
SendMessageHook(new BotSkillSaveComposer(chatEvent.botId, BotSkillsEnum.SETUP_CHAT, chatConfiguration));
|
|
||||||
close();
|
|
||||||
}, [automaticChat, chatDelay, chatEvent.botId, close, formatChatString, mixSentences, newText]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<DraggableWindow position={ DraggableWindowPosition.NOTHING } handleSelector=".drag-handler" style={ { top: getObjectLocation.y, left: getObjectLocation.x } }>
|
|
||||||
<div className="nitro-context-menu">
|
|
||||||
<div className="drag-handler">
|
|
||||||
<div className="px-2">
|
|
||||||
<div className="d-flex flex-column menu-item">
|
|
||||||
<p className="mb-1">{ LocalizeText('bot.skill.chatter.configuration.chat.text') }</p>
|
|
||||||
<textarea className="form-control form-control-sm mb-2" placeholder={LocalizeText('bot.skill.chatter.configuration.text.placeholder')} value={newText} rows={7} onChange={e => setNewText(e.target.value)}/>
|
|
||||||
</div>
|
|
||||||
<div className="d-flex flex-row menu-item">
|
|
||||||
<p className="mb-1 me-2">{ LocalizeText('bot.skill.chatter.configuration.automatic.chat') }</p>
|
|
||||||
<input type="checkbox" className="form-check-input" checked={automaticChat} onChange={e => setAutomaticChat(e.target.checked)} />
|
|
||||||
</div>
|
|
||||||
<div className="d-flex flex-row menu-item">
|
|
||||||
<p className="mb-1 me-2">{ LocalizeText('bot.skill.chatter.configuration.markov')}</p>
|
|
||||||
<input type="checkbox" className="form-check-input" checked={mixSentences} onChange={ e => setMixSentences(e.target.checked)} />
|
|
||||||
</div>
|
|
||||||
<div className="d-flex flex-row menu-item">
|
|
||||||
<p className="mb-1 me-2">{ LocalizeText('bot.skill.chatter.configuration.chat.delay') }</p>
|
|
||||||
<input type="number" className="form-control form-control-sm mb-2" value={chatDelay} onChange={e => setChatDelay(e.target.valueAsNumber)}/>
|
|
||||||
</div>
|
|
||||||
<div className="d-flex flex-row justify-content-between mt-1">
|
|
||||||
<button type="button" className="btn btn-secondary btn-sm" onClick={close}>{ LocalizeText('cancel')}</button>
|
|
||||||
<button type="button" className="btn btn-success btn-sm" onClick={save}>{ LocalizeText('save') }</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</DraggableWindow>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
import { RoomWidgetUpdateRentableBotChatEvent } from '../../../../../../api';
|
|
||||||
|
|
||||||
export interface AvatarInfoRentableBotChatViewProps
|
|
||||||
{
|
|
||||||
chatEvent: RoomWidgetUpdateRentableBotChatEvent;
|
|
||||||
close(): void;
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
import { RoomWidgetUpdateInfostandRentableBotEvent } from '../../../../../../api';
|
|
||||||
|
|
||||||
export interface AvatarInfoWidgetRentableBotViewProps
|
|
||||||
{
|
|
||||||
rentableBotData: RoomWidgetUpdateInfostandRentableBotEvent;
|
|
||||||
close: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface BotChatOptions
|
|
||||||
{
|
|
||||||
automaticChat: boolean;
|
|
||||||
chatDelay: number;
|
|
||||||
mixSentences: boolean;
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
import { UseProductItem } from '../../../../../../api';
|
|
||||||
|
|
||||||
export interface AvatarInfoUseProductConfirmViewProps
|
|
||||||
{
|
|
||||||
item: UseProductItem;
|
|
||||||
close: () => void;
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
import { UseProductItem } from '../../../../../../api';
|
|
||||||
|
|
||||||
export interface AvatarInfoUseProductViewProps
|
|
||||||
{
|
|
||||||
item: UseProductItem;
|
|
||||||
updateConfirmingProduct: (product: UseProductItem) => void;
|
|
||||||
close: () => void;
|
|
||||||
}
|
|
@ -1,8 +1,15 @@
|
|||||||
import { FC, MouseEvent, useCallback, useEffect, useState } from 'react';
|
import { FC, MouseEvent, useEffect, useState } from 'react';
|
||||||
import { Overlay, Popover } from 'react-bootstrap';
|
import { Overlay, Popover } from 'react-bootstrap';
|
||||||
import { BatchUpdates } from '../../../../../hooks';
|
import { Base, Flex, Grid } from '../../../../common';
|
||||||
import { NitroCardContentView, NitroCardGridItemView, NitroCardGridView } from '../../../../../layout';
|
import { BatchUpdates } from '../../../../hooks';
|
||||||
import { ChatInputStyleSelectorViewProps } from './ChatInputStyleSelectorView.types';
|
import { NitroCardContentView } from '../../../../layout';
|
||||||
|
|
||||||
|
interface ChatInputStyleSelectorViewProps
|
||||||
|
{
|
||||||
|
chatStyleId: number;
|
||||||
|
chatStyleIds: number[];
|
||||||
|
selectChatStyleId: (styleId: number) => void;
|
||||||
|
}
|
||||||
|
|
||||||
export const ChatInputStyleSelectorView: FC<ChatInputStyleSelectorViewProps> = props =>
|
export const ChatInputStyleSelectorView: FC<ChatInputStyleSelectorViewProps> = props =>
|
||||||
{
|
{
|
||||||
@ -10,13 +17,6 @@ export const ChatInputStyleSelectorView: FC<ChatInputStyleSelectorViewProps> = p
|
|||||||
const [ target, setTarget ] = useState<(EventTarget & HTMLElement)>(null);
|
const [ target, setTarget ] = useState<(EventTarget & HTMLElement)>(null);
|
||||||
const [ selectorVisible, setSelectorVisible ] = useState(false);
|
const [ selectorVisible, setSelectorVisible ] = useState(false);
|
||||||
|
|
||||||
useEffect(() =>
|
|
||||||
{
|
|
||||||
if(selectorVisible) return;
|
|
||||||
|
|
||||||
setTarget(null);
|
|
||||||
}, [ selectorVisible ]);
|
|
||||||
|
|
||||||
const selectStyle = (styleId: number) =>
|
const selectStyle = (styleId: number) =>
|
||||||
{
|
{
|
||||||
BatchUpdates(() =>
|
BatchUpdates(() =>
|
||||||
@ -26,7 +26,7 @@ export const ChatInputStyleSelectorView: FC<ChatInputStyleSelectorViewProps> = p
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const toggleSelector = useCallback((event: MouseEvent<HTMLElement>) =>
|
const toggleSelector = (event: MouseEvent<HTMLElement>) =>
|
||||||
{
|
{
|
||||||
BatchUpdates(() =>
|
BatchUpdates(() =>
|
||||||
{
|
{
|
||||||
@ -41,26 +41,33 @@ export const ChatInputStyleSelectorView: FC<ChatInputStyleSelectorViewProps> = p
|
|||||||
|
|
||||||
if(visible) setTarget((event.target as (EventTarget & HTMLElement)));
|
if(visible) setTarget((event.target as (EventTarget & HTMLElement)));
|
||||||
})
|
})
|
||||||
}, []);
|
}
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
if(selectorVisible) return;
|
||||||
|
|
||||||
|
setTarget(null);
|
||||||
|
}, [ selectorVisible ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<i className="icon chatstyles-icon cursor-pointer" onClick={ toggleSelector } />
|
<Base pointer className="icon chatstyles-icon" onClick={ toggleSelector } />
|
||||||
<Overlay show={ selectorVisible } target={ target } placement="top">
|
<Overlay show={ selectorVisible } target={ target } placement="top">
|
||||||
<Popover className="nitro-chat-style-selector-container" id="chat-style-selector">
|
<Popover className="nitro-chat-style-selector-container">
|
||||||
<NitroCardContentView className="bg-transparent overflow-hidden">
|
<NitroCardContentView overflow="hidden" className="bg-transparent">
|
||||||
<NitroCardGridView>
|
<Grid columnCount={ 3 } overflow="auto">
|
||||||
{ chatStyleIds && (chatStyleIds.length > 0) && chatStyleIds.map((styleId) =>
|
{ chatStyleIds && (chatStyleIds.length > 0) && chatStyleIds.map((styleId) =>
|
||||||
{
|
{
|
||||||
return (
|
return (
|
||||||
<NitroCardGridItemView key={ styleId } itemActive={ (chatStyleId === styleId) } onClick={ event => selectStyle(styleId) }>
|
<Flex center pointer key={ styleId } className="bubble-parent-container" onClick={ event => selectStyle(styleId) }>
|
||||||
<div className="bubble-container">
|
<Base key={ styleId } className="bubble-container">
|
||||||
<div className={ 'w-100 chat-bubble bubble-' + styleId }> </div>
|
<Base className={ `chat-bubble bubble-${ styleId }` }> </Base>
|
||||||
</div>
|
</Base>
|
||||||
</NitroCardGridItemView>
|
</Flex>
|
||||||
);
|
);
|
||||||
}) }
|
}) }
|
||||||
</NitroCardGridView>
|
</Grid>
|
||||||
</NitroCardContentView>
|
</NitroCardContentView>
|
||||||
</Popover>
|
</Popover>
|
||||||
</Overlay>
|
</Overlay>
|
@ -4,11 +4,12 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
border-radius: $border-radius;
|
border-radius: 8px;
|
||||||
border: 2px solid rgb(0, 0, 0);
|
border: 2px solid rgb(0, 0, 0);
|
||||||
background: #EDEDED;
|
background: #EDEDED;
|
||||||
padding-right: 10px;
|
padding-right: 10px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
@include media-breakpoint-down(sm) {
|
@include media-breakpoint-down(sm) {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -21,9 +22,8 @@
|
|||||||
&:before {
|
&:before {
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 98%;
|
width: 100%;
|
||||||
height: 5px;
|
height: 5px;
|
||||||
border-radius: $border-radius;
|
|
||||||
top: 1px;
|
top: 1px;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
@ -65,15 +65,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.nitro-chat-style-selector-button {
|
|
||||||
position: absolute;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
height: 100%;
|
|
||||||
right: 7px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nitro-chat-style-selector-container {
|
.nitro-chat-style-selector-container {
|
||||||
width: $chat-input-style-selector-widget-width;
|
width: $chat-input-style-selector-widget-width;
|
||||||
max-height: $chat-input-style-selector-widget-height;
|
max-height: $chat-input-style-selector-widget-height;
|
||||||
@ -82,20 +73,12 @@
|
|||||||
max-height: $chat-input-style-selector-widget-height !important;
|
max-height: $chat-input-style-selector-widget-height !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.grid-item {
|
.bubble-parent-container {
|
||||||
font-size: $font-size-sm;
|
height: 30px;
|
||||||
height: 30px !important;
|
|
||||||
border-color: unset !important;
|
|
||||||
border: 0 !important;
|
|
||||||
padding: 1px 3px;
|
|
||||||
|
|
||||||
&:not(.active) {
|
|
||||||
background-color: unset !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bubble-container {
|
.bubble-container {
|
||||||
visibility: visible;
|
position: relative;
|
||||||
width: 75%;
|
width: 50px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import { createPortal } from 'react-dom';
|
|||||||
import { GetConfiguration, GetSessionDataManager, LocalizeText, RoomWidgetChatMessage, RoomWidgetChatTypingMessage, RoomWidgetUpdateChatInputContentEvent, RoomWidgetUpdateInfostandUserEvent, RoomWidgetUpdateRoomObjectEvent } from '../../../../api';
|
import { GetConfiguration, GetSessionDataManager, LocalizeText, RoomWidgetChatMessage, RoomWidgetChatTypingMessage, RoomWidgetUpdateChatInputContentEvent, RoomWidgetUpdateInfostandUserEvent, RoomWidgetUpdateRoomObjectEvent } from '../../../../api';
|
||||||
import { CreateEventDispatcherHook } from '../../../../hooks/events';
|
import { CreateEventDispatcherHook } from '../../../../hooks/events';
|
||||||
import { useRoomContext } from '../../context/RoomContext';
|
import { useRoomContext } from '../../context/RoomContext';
|
||||||
import { ChatInputStyleSelectorView } from './style-selector/ChatInputStyleSelectorView';
|
import { ChatInputStyleSelectorView } from './ChatInputStyleSelectorView';
|
||||||
|
|
||||||
export const ChatInputView: FC<{}> = props =>
|
export const ChatInputView: FC<{}> = props =>
|
||||||
{
|
{
|
||||||
@ -118,7 +118,6 @@ export const ChatInputView: FC<{}> = props =>
|
|||||||
{
|
{
|
||||||
if(needsChatStyleUpdate)
|
if(needsChatStyleUpdate)
|
||||||
{
|
{
|
||||||
console.log('send')
|
|
||||||
GetSessionDataManager().sendChatStyleUpdate(chatStyleId);
|
GetSessionDataManager().sendChatStyleUpdate(chatStyleId);
|
||||||
|
|
||||||
setNeedsChatStyleUpdate(false);
|
setNeedsChatStyleUpdate(false);
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
export interface ChatInputStyleSelectorViewProps
|
|
||||||
{
|
|
||||||
chatStyleId: number;
|
|
||||||
chatStyleIds: number[];
|
|
||||||
selectChatStyleId: (styleId: number) => void;
|
|
||||||
}
|
|
@ -1,20 +1,20 @@
|
|||||||
import { FC, MouseEvent, useCallback, useEffect, useRef, useState } from 'react';
|
import { FC, MouseEvent, useEffect, useRef, useState } from 'react';
|
||||||
import { useRoomContext } from '../../../context/RoomContext';
|
import { ChatBubbleMessage } from './common/ChatBubbleMessage';
|
||||||
import { ChatWidgetMessageViewProps } from './ChatWidgetMessageView.types';
|
|
||||||
|
interface ChatWidgetMessageViewProps
|
||||||
|
{
|
||||||
|
chat: ChatBubbleMessage;
|
||||||
|
makeRoom: (chat: ChatBubbleMessage) => void;
|
||||||
|
onChatClicked: (chat: ChatBubbleMessage) => void;
|
||||||
|
}
|
||||||
|
|
||||||
export const ChatWidgetMessageView: FC<ChatWidgetMessageViewProps> = props =>
|
export const ChatWidgetMessageView: FC<ChatWidgetMessageViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { chat = null, makeRoom = null, onChatClicked = null } = props;
|
const { chat = null, makeRoom = null, onChatClicked = null } = props;
|
||||||
const [ isVisible, setIsVisible ] = useState(false);
|
const [ isVisible, setIsVisible ] = useState(false);
|
||||||
const { widgetHandler = null } = useRoomContext();
|
|
||||||
const elementRef = useRef<HTMLDivElement>();
|
const elementRef = useRef<HTMLDivElement>();
|
||||||
|
|
||||||
const onMouseDown = useCallback((event: MouseEvent<HTMLDivElement>) =>
|
const onMouseDown = (event: MouseEvent<HTMLDivElement>) => ((event.shiftKey) && onChatClicked(chat));
|
||||||
{
|
|
||||||
if(event.shiftKey) return;
|
|
||||||
|
|
||||||
onChatClicked(chat);
|
|
||||||
}, [ chat, onChatClicked ]);
|
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
@ -54,10 +54,7 @@ export const ChatWidgetMessageView: FC<ChatWidgetMessageViewProps> = props =>
|
|||||||
}
|
}
|
||||||
}, [ elementRef, chat, makeRoom ]);
|
}, [ elementRef, chat, makeRoom ]);
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() => setIsVisible(chat.visible), [ chat.visible ]);
|
||||||
{
|
|
||||||
setIsVisible(chat.visible);
|
|
||||||
}, [ chat.visible ]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={ elementRef } className="bubble-container" style={ { visibility: (isVisible ? 'visible' : 'hidden') } } onMouseDown={ onMouseDown }>
|
<div ref={ elementRef } className="bubble-container" style={ { visibility: (isVisible ? 'visible' : 'hidden') } } onMouseDown={ onMouseDown }>
|
@ -13,4 +13,907 @@
|
|||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@import './message/ChatWidgetMessageView';
|
.chat-mention {
|
||||||
|
padding: 1px 5px;
|
||||||
|
font-weight: bold;
|
||||||
|
background: rgba(0, 0, 0, .2);
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 100px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: blue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bubble-container {
|
||||||
|
position: absolute;
|
||||||
|
width: fit-content;
|
||||||
|
transition: top 0.2s ease 0s;
|
||||||
|
user-select: none;
|
||||||
|
pointer-events: all;
|
||||||
|
|
||||||
|
// -webkit-animation-duration: 0.2s;
|
||||||
|
// animation-duration: 0.2s;
|
||||||
|
// -webkit-animation-fill-mode: both;
|
||||||
|
// animation-fill-mode: both;
|
||||||
|
// -webkit-animation-name: bounceIn;
|
||||||
|
// animation-name: bounceIn;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:active {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-container-bg {
|
||||||
|
position: absolute;
|
||||||
|
top: -1px;
|
||||||
|
left: 1px;
|
||||||
|
width: 30px;
|
||||||
|
height: calc(100% - 0.5px);
|
||||||
|
border-radius: 7px;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-bubble {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
word-break: break-word;
|
||||||
|
max-width: 350px;
|
||||||
|
min-height: 25px;
|
||||||
|
font-size: 15px;
|
||||||
|
|
||||||
|
border-image-slice: 17 6 6 29 fill;
|
||||||
|
border-image-width: 17px 6px 6px 29px;
|
||||||
|
border-image-outset: 2px 0px 0px 0px;
|
||||||
|
border-image-repeat: repeat repeat;
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
|
||||||
|
width: 9px;
|
||||||
|
height: 6px;
|
||||||
|
bottom: -5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.type-0 { // normal
|
||||||
|
.message {
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.type-1 { // whisper
|
||||||
|
.message {
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: italic;
|
||||||
|
color: #595959;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.type-2 { // shout
|
||||||
|
.message {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-0 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_0_transparent.png');
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_0_1_33_34_pointer.png');
|
||||||
|
bottom: -5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-1 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_1.png');
|
||||||
|
|
||||||
|
border-image-slice: 18 6 6 29 fill;
|
||||||
|
border-image-width: 18px 6px 6px 29px;
|
||||||
|
border-image-outset: 3px 0px 0px 0px;
|
||||||
|
|
||||||
|
.user-container {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.username {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_0_1_33_34_pointer.png');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-2, &.bubble-31 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_2.png');
|
||||||
|
|
||||||
|
.user-container {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.username {
|
||||||
|
color: rgba($white, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.message {
|
||||||
|
color: rgba($white, 1) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_2_31_pointer.png');
|
||||||
|
height: 7px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-3 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_3.png');
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_3_pointer.png');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-4 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_4.png');
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_4_pointer.png');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-5 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_5.png');
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_5_pointer.png');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-6 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_6.png');
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_6_pointer.png');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-7 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_7.png');
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_7_pointer.png');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-8 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_8.png');
|
||||||
|
|
||||||
|
border-image-slice: 20 6 6 27 fill;
|
||||||
|
border-image-width: 20px 6px 6px 27px;
|
||||||
|
border-image-outset: 5px 0px 0px 0px;
|
||||||
|
|
||||||
|
.chat-content {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_8_pointer.png');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-9 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_9.png');
|
||||||
|
|
||||||
|
border-image-slice: 17 18 12 19 fill;
|
||||||
|
border-image-width: 17px 18px 12px 19px;
|
||||||
|
border-image-outset: 7px 7px 0px 9px;
|
||||||
|
|
||||||
|
.chat-content {
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_9_pointer.png');
|
||||||
|
width: 7px;
|
||||||
|
height: 10px;
|
||||||
|
bottom: -6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-10 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_10.png');
|
||||||
|
|
||||||
|
border-image-slice: 29 18 8 37 fill;
|
||||||
|
border-image-width: 29px 18px 8px 37px;
|
||||||
|
border-image-outset: 12px 7px 1px 5px;
|
||||||
|
|
||||||
|
.chat-content {
|
||||||
|
margin-left: 24px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_10_pointer.png');
|
||||||
|
width: 7px;
|
||||||
|
height: 8px;
|
||||||
|
bottom: -3px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-11 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_11.png');
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_11_pointer.png');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-12 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_12.png');
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_12_pointer.png');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-13 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_13.png');
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_13_pointer.png');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-14 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_14.png');
|
||||||
|
|
||||||
|
.chat-content {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_14_pointer.png');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-15 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_15.png');
|
||||||
|
|
||||||
|
.chat-content {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_15_pointer.png');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-16 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_16.png');
|
||||||
|
|
||||||
|
border-image-slice: 13 6 10 31 fill;
|
||||||
|
border-image-width: 13px 6px 10px 31px;
|
||||||
|
border-image-outset: 6px 0px 0px 0px;
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_16_pointer.png');
|
||||||
|
height: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-17 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_17.png');
|
||||||
|
|
||||||
|
border-image-slice: 24 6 8 35 fill;
|
||||||
|
border-image-width: 24px 6px 8px 35px;
|
||||||
|
border-image-outset: 9px 0px 2px 5px;
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_17_pointer.png');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-18 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_18.png');
|
||||||
|
|
||||||
|
border-image-slice: 7 16 8 16 fill;
|
||||||
|
border-image-width: 7px 16px 8px 16px;
|
||||||
|
border-image-outset: 3px 10px 2px 11px;
|
||||||
|
|
||||||
|
.chat-content {
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_18_pointer.png');
|
||||||
|
height: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-19 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_19.png');
|
||||||
|
|
||||||
|
border-image-slice: 17 6 9 19 fill;
|
||||||
|
border-image-width: 17px 6px 9px 19px;
|
||||||
|
border-image-outset: 5px 0px 0px 8px;
|
||||||
|
|
||||||
|
.chat-content {
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_19_20_pointer.png');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-20 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_20.png');
|
||||||
|
|
||||||
|
border-image-slice: 18 6 8 19 fill;
|
||||||
|
border-image-width: 18px 6px 8px 19px;
|
||||||
|
border-image-outset: 5px 0px 0px 8px;
|
||||||
|
|
||||||
|
.chat-content {
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_19_20_pointer.png');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-21 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_21.png');
|
||||||
|
|
||||||
|
border-image-slice: 20 6 12 24 fill;
|
||||||
|
border-image-width: 20px 6px 12px 24px;
|
||||||
|
border-image-outset: 13px 2px 1px 3px;
|
||||||
|
|
||||||
|
.chat-content {
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_21_pointer.png');
|
||||||
|
bottom: -4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-22 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_22.png');
|
||||||
|
|
||||||
|
border-image-slice: 18 19 11 33 fill;
|
||||||
|
border-image-width: 18px 19px 11px 33px;
|
||||||
|
border-image-outset: 7px 1px 1px 5px;
|
||||||
|
|
||||||
|
.chat-content {
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_22_pointer.png');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-23 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_23.png');
|
||||||
|
|
||||||
|
border-image-slice: 16 6 7 32 fill;
|
||||||
|
border-image-width: 16px 6px 7px 32px;
|
||||||
|
border-image-outset: 5px 0px 0px 3px;
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_23_37_pointer.png');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-24 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_24.png');
|
||||||
|
|
||||||
|
border-image-slice: 23 8 6 40 fill;
|
||||||
|
border-image-width: 23px 8px 6px 40px;
|
||||||
|
border-image-outset: 6px 0px 0px 6px;
|
||||||
|
|
||||||
|
.chat-content {
|
||||||
|
margin-left: 30px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_24_pointer.png');
|
||||||
|
bottom: -4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-25 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_25.png');
|
||||||
|
|
||||||
|
border-image-slice: 10 13 8 28 fill;
|
||||||
|
border-image-width: 10px 13px 8px 28px;
|
||||||
|
border-image-outset: 6px 3px 2px 0px;
|
||||||
|
|
||||||
|
.chat-content {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_25_pointer.png');
|
||||||
|
height: 9px;
|
||||||
|
bottom: -7px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-26 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_26.png');
|
||||||
|
|
||||||
|
border-image-slice: 16 9 8 29 fill;
|
||||||
|
border-image-width: 16px 9px 8px 29px;
|
||||||
|
border-image-outset: 2px 2px 2px 0px;
|
||||||
|
|
||||||
|
.chat-content {
|
||||||
|
color: #c59432;
|
||||||
|
text-shadow: 1px 1px rgba(0, 0, 0, .3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_26_pointer.png');
|
||||||
|
height: 10px;
|
||||||
|
bottom: -6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-27 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_27.png');
|
||||||
|
|
||||||
|
border-image-slice: 25 6 5 36 fill;
|
||||||
|
border-image-width: 25px 6px 5px 36px;
|
||||||
|
border-image-outset: 8px 0px 0px 5px;
|
||||||
|
|
||||||
|
.chat-content {
|
||||||
|
margin-left: 30px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_27_pointer.png');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-28 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_28.png');
|
||||||
|
|
||||||
|
border-image-slice: 16 7 7 27 fill;
|
||||||
|
border-image-width: 16px 7px 7px 27px;
|
||||||
|
border-image-outset: 3px 0px 0px 0px;
|
||||||
|
|
||||||
|
.chat-content {
|
||||||
|
margin-left: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_28_pointer.png');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-29 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_29.png');
|
||||||
|
|
||||||
|
border-image-slice: 10 7 15 31 fill;
|
||||||
|
border-image-width: 10px 7px 15px 31px;
|
||||||
|
border-image-outset: 2px 0px 0px 1px;
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_29_pointer.png');
|
||||||
|
bottom: -4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-30 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_30.png');
|
||||||
|
|
||||||
|
.user-container {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_30_pointer.png');
|
||||||
|
height: 7px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-32 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_32.png');
|
||||||
|
|
||||||
|
border-image-slice: 15 7 7 30 fill;
|
||||||
|
border-image-width: 15px 7px 7px 30px;
|
||||||
|
border-image-outset: 2px 0px 0px 0px;
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_32_pointer.png');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-33 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_33_34.png');
|
||||||
|
|
||||||
|
border-image-slice: 7 6 6 39 fill;
|
||||||
|
border-image-width: 7px 6px 6px 39px;
|
||||||
|
border-image-outset: 2px 0px 0px 0px;
|
||||||
|
|
||||||
|
.user-container {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-content {
|
||||||
|
margin-left: 35px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: ' ';
|
||||||
|
position: absolute;
|
||||||
|
width: 19px;
|
||||||
|
height: 19px;
|
||||||
|
left: 9px;
|
||||||
|
top: 2px;
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_33_extra.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_0_1_33_34_pointer.png');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-34 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_33_34.png');
|
||||||
|
|
||||||
|
border-image-slice: 7 6 6 39 fill;
|
||||||
|
border-image-width: 7px 6px 6px 39px;
|
||||||
|
border-image-outset: 2px 0px 0px 0px;
|
||||||
|
|
||||||
|
&.type-1 {
|
||||||
|
|
||||||
|
.message {
|
||||||
|
font-style: unset;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-container {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.username {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-content {
|
||||||
|
margin-left: 35px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: ' ';
|
||||||
|
position: absolute;
|
||||||
|
width: 19px;
|
||||||
|
height: 19px;
|
||||||
|
left: 9px;
|
||||||
|
top: 2px;
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_34_extra.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_0_1_33_34_pointer.png');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-35 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_35.png');
|
||||||
|
|
||||||
|
border-image-slice: 19 6 5 29 fill;
|
||||||
|
border-image-width: 19px 6px 5px 29px;
|
||||||
|
border-image-outset: 4px 0px 0px 0px;
|
||||||
|
|
||||||
|
.user-container {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_35_pointer.png');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-36 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_36.png');
|
||||||
|
|
||||||
|
border-image-slice: 17 7 5 30 fill;
|
||||||
|
border-image-width: 17px 7px 5px 30px;
|
||||||
|
border-image-outset: 2px 0px 0px 0px;
|
||||||
|
|
||||||
|
.user-container {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: ' ';
|
||||||
|
position: absolute;
|
||||||
|
width: 13px;
|
||||||
|
height: 18px;
|
||||||
|
left: 5px;
|
||||||
|
top: 2px;
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_36_extra.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_36_pointer.png');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-37 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_37.png');
|
||||||
|
|
||||||
|
border-image-slice: 16 6 7 32 fill;
|
||||||
|
border-image-width: 16px 6px 7px 32px;
|
||||||
|
border-image-outset: 5px 0px 0px 3px;
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_23_37_pointer.png');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-38 {
|
||||||
|
border-image-source: url('../../../../assets/images/chat/chatbubbles/bubble_38.png');
|
||||||
|
|
||||||
|
border-image-slice: 17 7 5 30 fill;
|
||||||
|
border-image-width: 17px 7px 5px 30px;
|
||||||
|
border-image-outset: 2px 0px 0px 0px;
|
||||||
|
|
||||||
|
.user-container {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: ' ';
|
||||||
|
position: absolute;
|
||||||
|
width: 19px;
|
||||||
|
height: 19px;
|
||||||
|
left: 3px;
|
||||||
|
top: 2px;
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_38_extra.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_38_pointer.png');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-container {
|
||||||
|
z-index: 3;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 100%;
|
||||||
|
max-height: 24px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.user-image {
|
||||||
|
position: absolute;
|
||||||
|
top: -48px;
|
||||||
|
left: -32.5px;
|
||||||
|
width: 90px;
|
||||||
|
height: 130px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
transform: scale(0.5);
|
||||||
|
overflow: hidden;
|
||||||
|
image-rendering: -webkit-optimize-contrast;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-content {
|
||||||
|
padding: 5px 6px 5px 4px;
|
||||||
|
margin-left: 27px;
|
||||||
|
line-height: 1;
|
||||||
|
color: $black;
|
||||||
|
min-height: 25px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-bubble-icon {
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
|
||||||
|
&.bubble-0 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_0.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-1 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_1.png');
|
||||||
|
height: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-2, &.bubble-31 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_2.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-3 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_3.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-4 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_4.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-5 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_5.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-6 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_6.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-7 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_7.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-8 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_8.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-9 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_9.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-10 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_10.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-11 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_11.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-12 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_12.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-13 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_13.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-14 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_14.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-15 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_15.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-16 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_16.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-17 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_17.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-18 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_18.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-19 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_19.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-20 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_20.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-21 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_21.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-22 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_22.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-23 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_23.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-24 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_24.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-25 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_25.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-26 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_26.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-27 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_27.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-28 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_28.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-29 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_29.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-30 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_30.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-32 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_32.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-33 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_33_34.png');
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: ' ';
|
||||||
|
position: absolute;
|
||||||
|
width: 19px;
|
||||||
|
height: 19px;
|
||||||
|
left: 11px;
|
||||||
|
top: 10px;
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_33_extra.png');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-34 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_33_34.png');
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: ' ';
|
||||||
|
position: absolute;
|
||||||
|
width: 19px;
|
||||||
|
height: 19px;
|
||||||
|
left: 11px;
|
||||||
|
top: 10px;
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_34_extra.png');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-35 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_35.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-36 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_36.png');
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: ' ';
|
||||||
|
position: absolute;
|
||||||
|
width: 13px;
|
||||||
|
height: 18px;
|
||||||
|
left: 13px;
|
||||||
|
top: 10px;
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_36_extra.png');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-37 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_35.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bubble-38 {
|
||||||
|
background-image: url('../../../../assets/images/chat/chatbubbles/bubble_38.png');
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: ' ';
|
||||||
|
position: absolute;
|
||||||
|
width: 19px;
|
||||||
|
height: 19px;
|
||||||
|
left: 11px;
|
||||||
|
top: 10px;
|
||||||
|
background: url('../../../../assets/images/chat/chatbubbles/bubble_38_extra.png');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -3,8 +3,8 @@ import { FC, useCallback, useEffect, useRef, useState } from 'react';
|
|||||||
import { RoomWidgetChatSelectAvatarMessage, RoomWidgetRoomObjectMessage, RoomWidgetUpdateChatEvent } from '../../../../api';
|
import { RoomWidgetChatSelectAvatarMessage, RoomWidgetRoomObjectMessage, RoomWidgetUpdateChatEvent } from '../../../../api';
|
||||||
import { CreateEventDispatcherHook, useRoomEngineEvent } from '../../../../hooks/events';
|
import { CreateEventDispatcherHook, useRoomEngineEvent } from '../../../../hooks/events';
|
||||||
import { useRoomContext } from '../../context/RoomContext';
|
import { useRoomContext } from '../../context/RoomContext';
|
||||||
import { ChatWidgetMessageView } from './message/ChatWidgetMessageView';
|
import { ChatWidgetMessageView } from './ChatWidgetMessageView';
|
||||||
import { ChatBubbleMessage } from './utils/ChatBubbleMessage';
|
import { ChatBubbleMessage } from './common/ChatBubbleMessage';
|
||||||
|
|
||||||
export const ChatWidgetView: FC<{}> = props =>
|
export const ChatWidgetView: FC<{}> = props =>
|
||||||
{
|
{
|
||||||
@ -54,13 +54,7 @@ export const ChatWidgetView: FC<{}> = props =>
|
|||||||
}
|
}
|
||||||
}, [ chatMessages, moveChatUp, removeHiddenChats ]);
|
}, [ chatMessages, moveChatUp, removeHiddenChats ]);
|
||||||
|
|
||||||
const addChat = useCallback((chat: ChatBubbleMessage) =>
|
const addChat = useCallback((chat: ChatBubbleMessage) => setChatMessages(prevValue => [ ...prevValue, chat ]), []);
|
||||||
{
|
|
||||||
setChatMessages(prevValue =>
|
|
||||||
{
|
|
||||||
return [ ...prevValue, chat ];
|
|
||||||
});
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const onRoomWidgetUpdateChatEvent = useCallback((event: RoomWidgetUpdateChatEvent) =>
|
const onRoomWidgetUpdateChatEvent = useCallback((event: RoomWidgetUpdateChatEvent) =>
|
||||||
{
|
{
|
||||||
@ -115,10 +109,7 @@ export const ChatWidgetView: FC<{}> = props =>
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={ elementRef } className="nitro-chat-widget">
|
<div ref={ elementRef } className="nitro-chat-widget">
|
||||||
{ chatMessages.map(chat =>
|
{ chatMessages.map(chat => <ChatWidgetMessageView key={ chat.id } chat={ chat } makeRoom={ makeRoom } onChatClicked={ onChatClicked } />) }
|
||||||
{
|
|
||||||
return <ChatWidgetMessageView key={ chat.id } chat={ chat } makeRoom={ makeRoom } onChatClicked={ onChatClicked } />
|
|
||||||
})}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,921 +0,0 @@
|
|||||||
@keyframes bounceIn {
|
|
||||||
0% {
|
|
||||||
opacity: 0;
|
|
||||||
transform: scale(.3);
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
opacity: 1;
|
|
||||||
transform: scale(1.1);
|
|
||||||
}
|
|
||||||
70% {
|
|
||||||
transform: scale(.9);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: scale(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-mention {
|
|
||||||
padding: 1px 5px;
|
|
||||||
font-weight: bold;
|
|
||||||
background: rgba(0, 0, 0, .2);
|
|
||||||
cursor: pointer;
|
|
||||||
border-radius: 100px;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: blue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.bubble-container {
|
|
||||||
position: absolute;
|
|
||||||
width: fit-content;
|
|
||||||
transition: top 0.2s ease 0s;
|
|
||||||
user-select: none;
|
|
||||||
pointer-events: all;
|
|
||||||
|
|
||||||
// -webkit-animation-duration: 0.2s;
|
|
||||||
// animation-duration: 0.2s;
|
|
||||||
// -webkit-animation-fill-mode: both;
|
|
||||||
// animation-fill-mode: both;
|
|
||||||
// -webkit-animation-name: bounceIn;
|
|
||||||
// animation-name: bounceIn;
|
|
||||||
|
|
||||||
&:hover,
|
|
||||||
&:active {
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-container-bg {
|
|
||||||
position: absolute;
|
|
||||||
top: -1px;
|
|
||||||
left: 1px;
|
|
||||||
width: 30px;
|
|
||||||
height: calc(100% - 0.5px);
|
|
||||||
border-radius: 7px;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-bubble {
|
|
||||||
position: relative;
|
|
||||||
z-index: 1;
|
|
||||||
word-break: break-word;
|
|
||||||
max-width: 350px;
|
|
||||||
min-height: 25px;
|
|
||||||
font-size: 15px;
|
|
||||||
|
|
||||||
border-image-slice: 17 6 6 29 fill;
|
|
||||||
border-image-width: 17px 6px 6px 29px;
|
|
||||||
border-image-outset: 2px 0px 0px 0px;
|
|
||||||
border-image-repeat: repeat repeat;
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
position: absolute;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
|
|
||||||
width: 9px;
|
|
||||||
height: 6px;
|
|
||||||
bottom: -5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.type-0 { // normal
|
|
||||||
.message {
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.type-1 { // whisper
|
|
||||||
.message {
|
|
||||||
font-weight: 400;
|
|
||||||
font-style: italic;
|
|
||||||
color: #595959;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.type-2 { // shout
|
|
||||||
.message {
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-0 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_0_transparent.png');
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_0_1_33_34_pointer.png');
|
|
||||||
bottom: -5px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-1 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_1.png');
|
|
||||||
|
|
||||||
border-image-slice: 18 6 6 29 fill;
|
|
||||||
border-image-width: 18px 6px 6px 29px;
|
|
||||||
border-image-outset: 3px 0px 0px 0px;
|
|
||||||
|
|
||||||
.user-container {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.username {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_0_1_33_34_pointer.png');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-2, &.bubble-31 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_2.png');
|
|
||||||
|
|
||||||
.user-container {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.username {
|
|
||||||
color: rgba($white, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.message {
|
|
||||||
color: rgba($white, 1) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_2_31_pointer.png');
|
|
||||||
height: 7px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-3 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_3.png');
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_3_pointer.png');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-4 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_4.png');
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_4_pointer.png');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-5 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_5.png');
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_5_pointer.png');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-6 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_6.png');
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_6_pointer.png');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-7 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_7.png');
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_7_pointer.png');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-8 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_8.png');
|
|
||||||
|
|
||||||
border-image-slice: 20 6 6 27 fill;
|
|
||||||
border-image-width: 20px 6px 6px 27px;
|
|
||||||
border-image-outset: 5px 0px 0px 0px;
|
|
||||||
|
|
||||||
.chat-content {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_8_pointer.png');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-9 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_9.png');
|
|
||||||
|
|
||||||
border-image-slice: 17 18 12 19 fill;
|
|
||||||
border-image-width: 17px 18px 12px 19px;
|
|
||||||
border-image-outset: 7px 7px 0px 9px;
|
|
||||||
|
|
||||||
.chat-content {
|
|
||||||
margin-left: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_9_pointer.png');
|
|
||||||
width: 7px;
|
|
||||||
height: 10px;
|
|
||||||
bottom: -6px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-10 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_10.png');
|
|
||||||
|
|
||||||
border-image-slice: 29 18 8 37 fill;
|
|
||||||
border-image-width: 29px 18px 8px 37px;
|
|
||||||
border-image-outset: 12px 7px 1px 5px;
|
|
||||||
|
|
||||||
.chat-content {
|
|
||||||
margin-left: 24px;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_10_pointer.png');
|
|
||||||
width: 7px;
|
|
||||||
height: 8px;
|
|
||||||
bottom: -3px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-11 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_11.png');
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_11_pointer.png');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-12 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_12.png');
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_12_pointer.png');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-13 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_13.png');
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_13_pointer.png');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-14 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_14.png');
|
|
||||||
|
|
||||||
.chat-content {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_14_pointer.png');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-15 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_15.png');
|
|
||||||
|
|
||||||
.chat-content {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_15_pointer.png');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-16 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_16.png');
|
|
||||||
|
|
||||||
border-image-slice: 13 6 10 31 fill;
|
|
||||||
border-image-width: 13px 6px 10px 31px;
|
|
||||||
border-image-outset: 6px 0px 0px 0px;
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_16_pointer.png');
|
|
||||||
height: 8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-17 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_17.png');
|
|
||||||
|
|
||||||
border-image-slice: 24 6 8 35 fill;
|
|
||||||
border-image-width: 24px 6px 8px 35px;
|
|
||||||
border-image-outset: 9px 0px 2px 5px;
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_17_pointer.png');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-18 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_18.png');
|
|
||||||
|
|
||||||
border-image-slice: 7 16 8 16 fill;
|
|
||||||
border-image-width: 7px 16px 8px 16px;
|
|
||||||
border-image-outset: 3px 10px 2px 11px;
|
|
||||||
|
|
||||||
.chat-content {
|
|
||||||
margin-left: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_18_pointer.png');
|
|
||||||
height: 8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-19 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_19.png');
|
|
||||||
|
|
||||||
border-image-slice: 17 6 9 19 fill;
|
|
||||||
border-image-width: 17px 6px 9px 19px;
|
|
||||||
border-image-outset: 5px 0px 0px 8px;
|
|
||||||
|
|
||||||
.chat-content {
|
|
||||||
margin-left: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_19_20_pointer.png');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-20 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_20.png');
|
|
||||||
|
|
||||||
border-image-slice: 18 6 8 19 fill;
|
|
||||||
border-image-width: 18px 6px 8px 19px;
|
|
||||||
border-image-outset: 5px 0px 0px 8px;
|
|
||||||
|
|
||||||
.chat-content {
|
|
||||||
margin-left: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_19_20_pointer.png');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-21 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_21.png');
|
|
||||||
|
|
||||||
border-image-slice: 20 6 12 24 fill;
|
|
||||||
border-image-width: 20px 6px 12px 24px;
|
|
||||||
border-image-outset: 13px 2px 1px 3px;
|
|
||||||
|
|
||||||
.chat-content {
|
|
||||||
margin-left: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_21_pointer.png');
|
|
||||||
bottom: -4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-22 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_22.png');
|
|
||||||
|
|
||||||
border-image-slice: 18 19 11 33 fill;
|
|
||||||
border-image-width: 18px 19px 11px 33px;
|
|
||||||
border-image-outset: 7px 1px 1px 5px;
|
|
||||||
|
|
||||||
.chat-content {
|
|
||||||
margin-left: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_22_pointer.png');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-23 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_23.png');
|
|
||||||
|
|
||||||
border-image-slice: 16 6 7 32 fill;
|
|
||||||
border-image-width: 16px 6px 7px 32px;
|
|
||||||
border-image-outset: 5px 0px 0px 3px;
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_23_37_pointer.png');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-24 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_24.png');
|
|
||||||
|
|
||||||
border-image-slice: 23 8 6 40 fill;
|
|
||||||
border-image-width: 23px 8px 6px 40px;
|
|
||||||
border-image-outset: 6px 0px 0px 6px;
|
|
||||||
|
|
||||||
.chat-content {
|
|
||||||
margin-left: 30px;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_24_pointer.png');
|
|
||||||
bottom: -4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-25 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_25.png');
|
|
||||||
|
|
||||||
border-image-slice: 10 13 8 28 fill;
|
|
||||||
border-image-width: 10px 13px 8px 28px;
|
|
||||||
border-image-outset: 6px 3px 2px 0px;
|
|
||||||
|
|
||||||
.chat-content {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_25_pointer.png');
|
|
||||||
height: 9px;
|
|
||||||
bottom: -7px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-26 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_26.png');
|
|
||||||
|
|
||||||
border-image-slice: 16 9 8 29 fill;
|
|
||||||
border-image-width: 16px 9px 8px 29px;
|
|
||||||
border-image-outset: 2px 2px 2px 0px;
|
|
||||||
|
|
||||||
.chat-content {
|
|
||||||
color: #c59432;
|
|
||||||
text-shadow: 1px 1px rgba(0, 0, 0, .3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_26_pointer.png');
|
|
||||||
height: 10px;
|
|
||||||
bottom: -6px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-27 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_27.png');
|
|
||||||
|
|
||||||
border-image-slice: 25 6 5 36 fill;
|
|
||||||
border-image-width: 25px 6px 5px 36px;
|
|
||||||
border-image-outset: 8px 0px 0px 5px;
|
|
||||||
|
|
||||||
.chat-content {
|
|
||||||
margin-left: 30px;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_27_pointer.png');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-28 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_28.png');
|
|
||||||
|
|
||||||
border-image-slice: 16 7 7 27 fill;
|
|
||||||
border-image-width: 16px 7px 7px 27px;
|
|
||||||
border-image-outset: 3px 0px 0px 0px;
|
|
||||||
|
|
||||||
.chat-content {
|
|
||||||
margin-left: 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_28_pointer.png');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-29 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_29.png');
|
|
||||||
|
|
||||||
border-image-slice: 10 7 15 31 fill;
|
|
||||||
border-image-width: 10px 7px 15px 31px;
|
|
||||||
border-image-outset: 2px 0px 0px 1px;
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_29_pointer.png');
|
|
||||||
bottom: -4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-30 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_30.png');
|
|
||||||
|
|
||||||
.user-container {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_30_pointer.png');
|
|
||||||
height: 7px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-32 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_32.png');
|
|
||||||
|
|
||||||
border-image-slice: 15 7 7 30 fill;
|
|
||||||
border-image-width: 15px 7px 7px 30px;
|
|
||||||
border-image-outset: 2px 0px 0px 0px;
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_32_pointer.png');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-33 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_33_34.png');
|
|
||||||
|
|
||||||
border-image-slice: 7 6 6 39 fill;
|
|
||||||
border-image-width: 7px 6px 6px 39px;
|
|
||||||
border-image-outset: 2px 0px 0px 0px;
|
|
||||||
|
|
||||||
.user-container {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-content {
|
|
||||||
margin-left: 35px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
content: ' ';
|
|
||||||
position: absolute;
|
|
||||||
width: 19px;
|
|
||||||
height: 19px;
|
|
||||||
left: 9px;
|
|
||||||
top: 2px;
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_33_extra.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_0_1_33_34_pointer.png');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-34 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_33_34.png');
|
|
||||||
|
|
||||||
border-image-slice: 7 6 6 39 fill;
|
|
||||||
border-image-width: 7px 6px 6px 39px;
|
|
||||||
border-image-outset: 2px 0px 0px 0px;
|
|
||||||
|
|
||||||
&.type-1 {
|
|
||||||
|
|
||||||
.message {
|
|
||||||
font-style: unset;
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-container {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.username {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-content {
|
|
||||||
margin-left: 35px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
content: ' ';
|
|
||||||
position: absolute;
|
|
||||||
width: 19px;
|
|
||||||
height: 19px;
|
|
||||||
left: 9px;
|
|
||||||
top: 2px;
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_34_extra.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_0_1_33_34_pointer.png');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-35 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_35.png');
|
|
||||||
|
|
||||||
border-image-slice: 19 6 5 29 fill;
|
|
||||||
border-image-width: 19px 6px 5px 29px;
|
|
||||||
border-image-outset: 4px 0px 0px 0px;
|
|
||||||
|
|
||||||
.user-container {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_35_pointer.png');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-36 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_36.png');
|
|
||||||
|
|
||||||
border-image-slice: 17 7 5 30 fill;
|
|
||||||
border-image-width: 17px 7px 5px 30px;
|
|
||||||
border-image-outset: 2px 0px 0px 0px;
|
|
||||||
|
|
||||||
.user-container {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
content: ' ';
|
|
||||||
position: absolute;
|
|
||||||
width: 13px;
|
|
||||||
height: 18px;
|
|
||||||
left: 5px;
|
|
||||||
top: 2px;
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_36_extra.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_36_pointer.png');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-37 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_37.png');
|
|
||||||
|
|
||||||
border-image-slice: 16 6 7 32 fill;
|
|
||||||
border-image-width: 16px 6px 7px 32px;
|
|
||||||
border-image-outset: 5px 0px 0px 3px;
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_23_37_pointer.png');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-38 {
|
|
||||||
border-image-source: url('../../../../../assets/images/chat/chatbubbles/bubble_38.png');
|
|
||||||
|
|
||||||
border-image-slice: 17 7 5 30 fill;
|
|
||||||
border-image-width: 17px 7px 5px 30px;
|
|
||||||
border-image-outset: 2px 0px 0px 0px;
|
|
||||||
|
|
||||||
.user-container {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
content: ' ';
|
|
||||||
position: absolute;
|
|
||||||
width: 19px;
|
|
||||||
height: 19px;
|
|
||||||
left: 3px;
|
|
||||||
top: 2px;
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_38_extra.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
.pointer {
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_38_pointer.png');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-container {
|
|
||||||
z-index: 3;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
height: 100%;
|
|
||||||
max-height: 24px;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
.user-image {
|
|
||||||
position: absolute;
|
|
||||||
top: -48px;
|
|
||||||
left: -32.5px;
|
|
||||||
width: 90px;
|
|
||||||
height: 130px;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: center;
|
|
||||||
transform: scale(0.5);
|
|
||||||
overflow: hidden;
|
|
||||||
image-rendering: -webkit-optimize-contrast;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-content {
|
|
||||||
padding: 5px 6px 5px 4px;
|
|
||||||
margin-left: 27px;
|
|
||||||
line-height: 1;
|
|
||||||
color: $black;
|
|
||||||
min-height: 25px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-bubble-icon {
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: center;
|
|
||||||
|
|
||||||
&.bubble-0 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_0.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-1 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_1.png');
|
|
||||||
height: 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-2, &.bubble-31 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_2.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-3 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_3.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-4 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_4.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-5 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_5.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-6 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_6.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-7 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_7.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-8 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_8.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-9 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_9.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-10 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_10.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-11 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_11.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-12 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_12.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-13 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_13.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-14 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_14.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-15 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_15.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-16 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_16.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-17 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_17.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-18 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_18.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-19 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_19.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-20 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_20.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-21 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_21.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-22 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_22.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-23 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_23.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-24 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_24.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-25 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_25.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-26 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_26.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-27 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_27.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-28 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_28.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-29 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_29.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-30 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_30.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-32 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_32.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-33 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_33_34.png');
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
content: ' ';
|
|
||||||
position: absolute;
|
|
||||||
width: 19px;
|
|
||||||
height: 19px;
|
|
||||||
left: 11px;
|
|
||||||
top: 10px;
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_33_extra.png');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-34 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_33_34.png');
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
content: ' ';
|
|
||||||
position: absolute;
|
|
||||||
width: 19px;
|
|
||||||
height: 19px;
|
|
||||||
left: 11px;
|
|
||||||
top: 10px;
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_34_extra.png');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-35 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_35.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-36 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_36.png');
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
content: ' ';
|
|
||||||
position: absolute;
|
|
||||||
width: 13px;
|
|
||||||
height: 18px;
|
|
||||||
left: 13px;
|
|
||||||
top: 10px;
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_36_extra.png');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-37 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_35.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bubble-38 {
|
|
||||||
background-image: url('../../../../../assets/images/chat/chatbubbles/bubble_38.png');
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
content: ' ';
|
|
||||||
position: absolute;
|
|
||||||
width: 19px;
|
|
||||||
height: 19px;
|
|
||||||
left: 11px;
|
|
||||||
top: 10px;
|
|
||||||
background: url('../../../../../assets/images/chat/chatbubbles/bubble_38_extra.png');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
import { ChatBubbleMessage } from '../utils/ChatBubbleMessage';
|
|
||||||
|
|
||||||
export interface ChatWidgetMessageViewProps
|
|
||||||
{
|
|
||||||
chat: ChatBubbleMessage;
|
|
||||||
makeRoom: (chat: ChatBubbleMessage) => void;
|
|
||||||
onChatClicked: (chat: ChatBubbleMessage) => void;
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
import { INitroPoint, IVector3D, NitroPoint } from '@nitrots/nitro-renderer';
|
|
||||||
import { GetRoomEngine } from '../../../../../api';
|
|
||||||
|
|
||||||
export function GetBubbleLocation(roomId: number, userLocation: IVector3D, canvasId = 1): INitroPoint
|
|
||||||
{
|
|
||||||
const geometry = GetRoomEngine().getRoomInstanceGeometry(roomId, canvasId);
|
|
||||||
const scale = GetRoomEngine().getRoomInstanceRenderingCanvasScale(roomId, canvasId);
|
|
||||||
|
|
||||||
let x = ((document.body.offsetWidth * scale) / 2);
|
|
||||||
let y = ((document.body.offsetHeight * scale) / 2);
|
|
||||||
|
|
||||||
if(geometry && userLocation)
|
|
||||||
{
|
|
||||||
const screenPoint = geometry.getScreenPoint(userLocation);
|
|
||||||
|
|
||||||
if(screenPoint)
|
|
||||||
{
|
|
||||||
x = (x + (screenPoint.x * scale));
|
|
||||||
y = (y + (screenPoint.y * scale));
|
|
||||||
|
|
||||||
const offsetPoint = GetRoomEngine().getRoomInstanceRenderingCanvasOffset(roomId, canvasId);
|
|
||||||
|
|
||||||
if(offsetPoint)
|
|
||||||
{
|
|
||||||
x = (x + offsetPoint.x);
|
|
||||||
y = (y + offsetPoint.y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new NitroPoint(x, y);
|
|
||||||
}
|
|
@ -1,16 +1,4 @@
|
|||||||
.nitro-chooser-widget {
|
.nitro-chooser-widget {
|
||||||
|
width: $nitro-chooser-width;
|
||||||
|
height: $nitro-chooser-height;
|
||||||
.chooser-container {
|
|
||||||
min-height: 150px;
|
|
||||||
|
|
||||||
.list-item {
|
|
||||||
color: black;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
&.selected {
|
|
||||||
background-color: cadetblue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -2,16 +2,24 @@ import { FC, useCallback, useMemo, useState } from 'react';
|
|||||||
import { AutoSizer, List, ListRowProps, ListRowRenderer } from 'react-virtualized';
|
import { AutoSizer, List, ListRowProps, ListRowRenderer } from 'react-virtualized';
|
||||||
import { RoomObjectItem, RoomWidgetRoomObjectMessage } from '../../../../api';
|
import { RoomObjectItem, RoomWidgetRoomObjectMessage } from '../../../../api';
|
||||||
import { LocalizeText } from '../../../../api/utils';
|
import { LocalizeText } from '../../../../api/utils';
|
||||||
|
import { Column, Flex, Text } from '../../../../common';
|
||||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout';
|
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout';
|
||||||
import { useRoomContext } from '../../context/RoomContext';
|
import { useRoomContext } from '../../context/RoomContext';
|
||||||
import { ChooserWidgetViewProps } from './ChooserWidgetView.type';
|
|
||||||
|
interface ChooserWidgetViewProps
|
||||||
|
{
|
||||||
|
title: string;
|
||||||
|
items: RoomObjectItem[];
|
||||||
|
displayItemId: boolean;
|
||||||
|
onCloseClick: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
export const ChooserWidgetView: FC<ChooserWidgetViewProps> = props =>
|
export const ChooserWidgetView: FC<ChooserWidgetViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { title = null, items = null, displayItemId = false, onCloseClick = null } = props;
|
const { title = null, items = null, displayItemId = false, onCloseClick = null } = props;
|
||||||
const [ selectedItem, setSelectedItem ] = useState<RoomObjectItem>(null);
|
const [ selectedItem, setSelectedItem ] = useState<RoomObjectItem>(null);
|
||||||
const [ searchValue, setSearchValue ] = useState('');
|
const [ searchValue, setSearchValue ] = useState('');
|
||||||
const { eventDispatcher = null, widgetHandler = null } = useRoomContext();
|
const { widgetHandler = null } = useRoomContext();
|
||||||
|
|
||||||
const filteredItems = useMemo(() =>
|
const filteredItems = useMemo(() =>
|
||||||
{
|
{
|
||||||
@ -21,15 +29,13 @@ export const ChooserWidgetView: FC<ChooserWidgetViewProps> = props =>
|
|||||||
|
|
||||||
const value = searchValue.toLocaleLowerCase();
|
const value = searchValue.toLocaleLowerCase();
|
||||||
|
|
||||||
return items.filter(item =>
|
return items.filter(item => item.name.toLocaleLowerCase().includes(value));
|
||||||
{
|
|
||||||
return item.name.toLocaleLowerCase().includes(value);
|
|
||||||
});
|
|
||||||
}, [ items, searchValue ]);
|
}, [ items, searchValue ]);
|
||||||
|
|
||||||
const onItemClick = useCallback((item: RoomObjectItem) =>
|
const onItemClick = useCallback((item: RoomObjectItem) =>
|
||||||
{
|
{
|
||||||
setSelectedItem(item);
|
setSelectedItem(item);
|
||||||
|
|
||||||
widgetHandler.processWidgetMessage(new RoomWidgetRoomObjectMessage(RoomWidgetRoomObjectMessage.SELECT_OBJECT, item.id, item.category));
|
widgetHandler.processWidgetMessage(new RoomWidgetRoomObjectMessage(RoomWidgetRoomObjectMessage.SELECT_OBJECT, item.id, item.category));
|
||||||
}, [ widgetHandler, setSelectedItem]);
|
}, [ widgetHandler, setSelectedItem]);
|
||||||
|
|
||||||
@ -38,24 +44,20 @@ export const ChooserWidgetView: FC<ChooserWidgetViewProps> = props =>
|
|||||||
const item = filteredItems[props.index];
|
const item = filteredItems[props.index];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={ props.key } className={ 'list-item' + ((selectedItem === item) ? ' selected' : '') } style={ props.style } onClick={ () => onItemClick(item) }>
|
<Flex key={ props.key } alignItems="center" position="absolute" className={ 'rounded px-1' + ((selectedItem === item) ? ' bg-muted' : '') } pointer style={ props.style } onClick={ event => onItemClick(item) }>
|
||||||
{ item.name } { displayItemId && (' - ' + item.id) }
|
<Text truncate>{ item.name } { displayItemId && (' - ' + item.id) }</Text>
|
||||||
</div>
|
</Flex>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NitroCardView className="nitro-chooser-widget">
|
<NitroCardView className="nitro-chooser-widget">
|
||||||
<NitroCardHeaderView headerText={ title } onCloseClick={ onCloseClick } />
|
<NitroCardHeaderView headerText={ title } onCloseClick={ onCloseClick } />
|
||||||
<NitroCardContentView>
|
<NitroCardContentView overflow="hidden">
|
||||||
<div className="d-flex mb-1">
|
|
||||||
<div className="d-flex flex-grow-1 me-1">
|
|
||||||
<input type="text" className="form-control form-control-sm" placeholder={ LocalizeText('generic.search') } value={searchValue} onChange={event => setSearchValue(event.target.value)} />
|
<input type="text" className="form-control form-control-sm" placeholder={ LocalizeText('generic.search') } value={searchValue} onChange={event => setSearchValue(event.target.value)} />
|
||||||
</div>
|
<Column fullHeight overflow="auto">
|
||||||
</div>
|
<AutoSizer defaultWidth={ 0 } defaultHeight={ 0 }>
|
||||||
<div className="row w-100 h-100 chooser-container">
|
{ ({ width, height }) =>
|
||||||
<AutoSizer defaultWidth={150} defaultHeight={150}>
|
|
||||||
{({ height, width }) =>
|
|
||||||
{
|
{
|
||||||
return (<List
|
return (<List
|
||||||
width={ width }
|
width={ width }
|
||||||
@ -65,7 +67,7 @@ export const ChooserWidgetView: FC<ChooserWidgetViewProps> = props =>
|
|||||||
rowRenderer={ rowRenderer } />)
|
rowRenderer={ rowRenderer } />)
|
||||||
} }
|
} }
|
||||||
</AutoSizer>
|
</AutoSizer>
|
||||||
</div>
|
</Column>
|
||||||
</NitroCardContentView>
|
</NitroCardContentView>
|
||||||
</NitroCardView>
|
</NitroCardView>
|
||||||
);
|
);
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
import { RoomObjectItem } from '../../../../api';
|
|
||||||
|
|
||||||
export interface ChooserWidgetViewProps
|
|
||||||
{
|
|
||||||
title: string;
|
|
||||||
items: RoomObjectItem[];
|
|
||||||
displayItemId: boolean;
|
|
||||||
onCloseClick: () => void;
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
import { FC, useCallback, useState } from 'react';
|
import { FC, useCallback, useState } from 'react';
|
||||||
import { LocalizeText, RoomObjectItem, RoomWidgetChooserContentEvent, RoomWidgetRequestWidgetMessage, RoomWidgetUpdateRoomObjectEvent } from '../../../../api';
|
import { LocalizeText, RoomObjectItem, RoomWidgetChooserContentEvent, RoomWidgetRequestWidgetMessage, RoomWidgetUpdateRoomObjectEvent } from '../../../../api';
|
||||||
import { CreateEventDispatcherHook } from '../../../../hooks';
|
import { BatchUpdates, CreateEventDispatcherHook } from '../../../../hooks';
|
||||||
import { useRoomContext } from '../../context/RoomContext';
|
import { useRoomContext } from '../../context/RoomContext';
|
||||||
import { ChooserWidgetView } from './ChooserWidgetView';
|
import { ChooserWidgetView } from './ChooserWidgetView';
|
||||||
|
|
||||||
@ -20,13 +20,16 @@ export const FurniChooserWidgetView: FC<{}> = props =>
|
|||||||
if(prevValue) clearTimeout(prevValue);
|
if(prevValue) clearTimeout(prevValue);
|
||||||
|
|
||||||
return setTimeout(() => widgetHandler.processWidgetMessage(new RoomWidgetRequestWidgetMessage(RoomWidgetRequestWidgetMessage.FURNI_CHOOSER)), 100);
|
return setTimeout(() => widgetHandler.processWidgetMessage(new RoomWidgetRequestWidgetMessage(RoomWidgetRequestWidgetMessage.FURNI_CHOOSER)), 100);
|
||||||
})
|
});
|
||||||
}, [ isVisible, widgetHandler ]);
|
}, [ isVisible, widgetHandler ]);
|
||||||
|
|
||||||
const onRoomWidgetChooserContentEvent = useCallback((event: RoomWidgetChooserContentEvent) =>
|
const onRoomWidgetChooserContentEvent = useCallback((event: RoomWidgetChooserContentEvent) =>
|
||||||
|
{
|
||||||
|
BatchUpdates(() =>
|
||||||
{
|
{
|
||||||
setItems(event.items);
|
setItems(event.items);
|
||||||
setIsVisible(true);
|
setIsVisible(true);
|
||||||
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
CreateEventDispatcherHook(RoomWidgetChooserContentEvent.FURNI_CHOOSER_CONTENT, eventDispatcher, onRoomWidgetChooserContentEvent);
|
CreateEventDispatcherHook(RoomWidgetChooserContentEvent.FURNI_CHOOSER_CONTENT, eventDispatcher, onRoomWidgetChooserContentEvent);
|
||||||
@ -48,12 +51,15 @@ export const FurniChooserWidgetView: FC<{}> = props =>
|
|||||||
CreateEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
|
CreateEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
|
||||||
|
|
||||||
const close = useCallback(() =>
|
const close = useCallback(() =>
|
||||||
|
{
|
||||||
|
BatchUpdates(() =>
|
||||||
{
|
{
|
||||||
setIsVisible(false);
|
setIsVisible(false);
|
||||||
setItems(null);
|
setItems(null);
|
||||||
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
if(!isVisible) return null;
|
if(!items) return null;
|
||||||
|
|
||||||
return <ChooserWidgetView title={ LocalizeText('widget.chooser.furni.title') } displayItemId={ true } items={ items } onCloseClick={ close } />;
|
return <ChooserWidgetView title={ LocalizeText('widget.chooser.furni.title') } displayItemId={ true } items={ items } onCloseClick={ close } />;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { FC, useCallback, useState } from 'react';
|
import { FC, useCallback, useState } from 'react';
|
||||||
import { LocalizeText, RoomObjectItem, RoomWidgetChooserContentEvent, RoomWidgetRequestWidgetMessage, RoomWidgetUpdateRoomObjectEvent } from '../../../../api';
|
import { LocalizeText, RoomObjectItem, RoomWidgetChooserContentEvent, RoomWidgetRequestWidgetMessage, RoomWidgetUpdateRoomObjectEvent } from '../../../../api';
|
||||||
import { CreateEventDispatcherHook } from '../../../../hooks';
|
import { BatchUpdates, CreateEventDispatcherHook } from '../../../../hooks';
|
||||||
import { useRoomContext } from '../../context/RoomContext';
|
import { useRoomContext } from '../../context/RoomContext';
|
||||||
import { ChooserWidgetView } from './ChooserWidgetView';
|
import { ChooserWidgetView } from './ChooserWidgetView';
|
||||||
|
|
||||||
@ -24,9 +24,12 @@ export const UserChooserWidgetView: FC<{}> = props =>
|
|||||||
}, [ isVisible, widgetHandler ]);
|
}, [ isVisible, widgetHandler ]);
|
||||||
|
|
||||||
const onRoomWidgetChooserContentEvent = useCallback((event: RoomWidgetChooserContentEvent) =>
|
const onRoomWidgetChooserContentEvent = useCallback((event: RoomWidgetChooserContentEvent) =>
|
||||||
|
{
|
||||||
|
BatchUpdates(() =>
|
||||||
{
|
{
|
||||||
setItems(event.items);
|
setItems(event.items);
|
||||||
setIsVisible(true);
|
setIsVisible(true);
|
||||||
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
CreateEventDispatcherHook(RoomWidgetChooserContentEvent.USER_CHOOSER_CONTENT, eventDispatcher, onRoomWidgetChooserContentEvent);
|
CreateEventDispatcherHook(RoomWidgetChooserContentEvent.USER_CHOOSER_CONTENT, eventDispatcher, onRoomWidgetChooserContentEvent);
|
||||||
@ -48,9 +51,12 @@ export const UserChooserWidgetView: FC<{}> = props =>
|
|||||||
CreateEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.USER_REMOVED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
|
CreateEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.USER_REMOVED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
|
||||||
|
|
||||||
const close = useCallback(() =>
|
const close = useCallback(() =>
|
||||||
|
{
|
||||||
|
BatchUpdates(() =>
|
||||||
{
|
{
|
||||||
setIsVisible(false);
|
setIsVisible(false);
|
||||||
setItems(null);
|
setItems(null);
|
||||||
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
if(!isVisible) return null;
|
if(!isVisible) return null;
|
||||||
|
@ -9,6 +9,11 @@
|
|||||||
z-index: $context-menu-zindex;
|
z-index: $context-menu-zindex;
|
||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
|
|
||||||
|
&.bot-chat {
|
||||||
|
max-width: 250px;
|
||||||
|
width: 250px;
|
||||||
|
}
|
||||||
|
|
||||||
&.name-only {
|
&.name-only {
|
||||||
background-color: rgba($black, 0.5);
|
background-color: rgba($black, 0.5);
|
||||||
padding: 1px 8px;
|
padding: 1px 8px;
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
import { FC, useMemo } from 'react';
|
||||||
|
import { Flex, FlexProps } from '../../../../common';
|
||||||
|
|
||||||
|
export const ContextMenuHeaderView: FC<FlexProps> = props =>
|
||||||
|
{
|
||||||
|
const { justifyContent = 'center', alignItems = 'center', classNames = [], ...rest } = props;
|
||||||
|
|
||||||
|
const getClassNames = useMemo(() =>
|
||||||
|
{
|
||||||
|
const newClassNames: string[] = [ 'menu-header', 'p-1' ];
|
||||||
|
|
||||||
|
if(classNames.length) newClassNames.push(...classNames);
|
||||||
|
|
||||||
|
return newClassNames;
|
||||||
|
}, [ classNames ]);
|
||||||
|
|
||||||
|
return <Flex justifyContent={ justifyContent } alignItems={ alignItems } classNames={ getClassNames } { ...rest } />;
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
import { FC, MouseEvent, useMemo } from 'react';
|
||||||
|
import { Flex, FlexProps } from '../../../../common';
|
||||||
|
|
||||||
|
interface ContextMenuListItemViewProps extends FlexProps
|
||||||
|
{
|
||||||
|
disabled?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ContextMenuListItemView: FC<ContextMenuListItemViewProps> = props =>
|
||||||
|
{
|
||||||
|
const { disabled = false, fullWidth = true, justifyContent = 'center', alignItems = 'center', classNames = [], onClick = null, ...rest } = props;
|
||||||
|
|
||||||
|
const handleClick = (event: MouseEvent<HTMLDivElement>) =>
|
||||||
|
{
|
||||||
|
if(disabled) return;
|
||||||
|
|
||||||
|
if(onClick) onClick(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
const getClassNames = useMemo(() =>
|
||||||
|
{
|
||||||
|
const newClassNames: string[] = [ 'menu-item', 'list-item' ];
|
||||||
|
|
||||||
|
if(disabled) newClassNames.push('disabled');
|
||||||
|
|
||||||
|
if(classNames.length) newClassNames.push(...classNames);
|
||||||
|
|
||||||
|
return newClassNames;
|
||||||
|
}, [ disabled, classNames ]);
|
||||||
|
|
||||||
|
return <Flex fullWidth={ fullWidth } justifyContent={ justifyContent } alignItems={ alignItems } classNames={ getClassNames } onClick={ handleClick } { ...rest } />;
|
||||||
|
}
|
18
src/views/room/widgets/context-menu/ContextMenuListView.tsx
Normal file
18
src/views/room/widgets/context-menu/ContextMenuListView.tsx
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { FC, useMemo } from 'react';
|
||||||
|
import { Column, ColumnProps } from '../../../../common';
|
||||||
|
|
||||||
|
export const ContextMenuListView: FC<ColumnProps> = props =>
|
||||||
|
{
|
||||||
|
const { classNames = [], ...rest } = props;
|
||||||
|
|
||||||
|
const getClassNames = useMemo(() =>
|
||||||
|
{
|
||||||
|
const newClassNames: string[] = [ 'menu-list' ];
|
||||||
|
|
||||||
|
if(classNames.length) newClassNames.push(...classNames);
|
||||||
|
|
||||||
|
return newClassNames;
|
||||||
|
}, [ classNames ]);
|
||||||
|
|
||||||
|
return <Column classNames={ getClassNames } { ...rest } />
|
||||||
|
}
|
@ -1,7 +1,17 @@
|
|||||||
import { FixedSizeStack, NitroPoint, NitroRectangle, RoomObjectType } from '@nitrots/nitro-renderer';
|
import { FixedSizeStack, NitroPoint, NitroRectangle, RoomObjectType } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback, useEffect, useRef, useState } from 'react';
|
import { CSSProperties, FC, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { GetNitroInstance, GetRoomEngine, GetRoomObjectBounds, GetRoomSession, GetTicker } from '../../../../api';
|
import { GetNitroInstance, GetRoomEngine, GetRoomObjectBounds, GetRoomSession, GetTicker } from '../../../../api';
|
||||||
import { ContextMenuViewProps } from './ContextMenuView.types';
|
import { Base, BaseProps } from '../../../../common';
|
||||||
|
import { BatchUpdates } from '../../../../hooks';
|
||||||
|
|
||||||
|
interface ContextMenuViewProps extends BaseProps<HTMLDivElement>
|
||||||
|
{
|
||||||
|
objectId: number;
|
||||||
|
category: number;
|
||||||
|
userType?: number;
|
||||||
|
fades?: boolean;
|
||||||
|
close: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
const LOCATION_STACK_SIZE: number = 25;
|
const LOCATION_STACK_SIZE: number = 25;
|
||||||
const BUBBLE_DROP_SPEED: number = 3;
|
const BUBBLE_DROP_SPEED: number = 3;
|
||||||
@ -11,7 +21,7 @@ const SPACE_AROUND_EDGES = 10;
|
|||||||
|
|
||||||
export const ContextMenuView: FC<ContextMenuViewProps> = props =>
|
export const ContextMenuView: FC<ContextMenuViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { objectId = -1, category = -1, userType = -1, fades = false, className = '', close = null, children = null } = props;
|
const { objectId = -1, category = -1, userType = -1, fades = false, close = null, position = 'absolute', classNames = [], style = {}, ...rest } = props;
|
||||||
const [ pos, setPos ] = useState<{ x: number, y: number }>({ x: null, y: null });
|
const [ pos, setPos ] = useState<{ x: number, y: number }>({ x: null, y: null });
|
||||||
const [ deltaYStack, setDeltaYStack ] = useState<FixedSizeStack>(null);
|
const [ deltaYStack, setDeltaYStack ] = useState<FixedSizeStack>(null);
|
||||||
const [ currentDeltaY, setCurrentDeltaY ] = useState(-1000000);
|
const [ currentDeltaY, setCurrentDeltaY ] = useState(-1000000);
|
||||||
@ -92,8 +102,11 @@ export const ContextMenuView: FC<ContextMenuViewProps> = props =>
|
|||||||
if(y < SPACE_AROUND_EDGES) y = SPACE_AROUND_EDGES;
|
if(y < SPACE_AROUND_EDGES) y = SPACE_AROUND_EDGES;
|
||||||
else if(y > maxTop) y = maxTop;
|
else if(y > maxTop) y = maxTop;
|
||||||
|
|
||||||
|
BatchUpdates(() =>
|
||||||
|
{
|
||||||
setCurrentDeltaY(maxStack);
|
setCurrentDeltaY(maxStack);
|
||||||
setPos({ x, y });
|
setPos({ x, y });
|
||||||
|
});
|
||||||
}, [ deltaYStack, currentDeltaY, getOffset ]);
|
}, [ deltaYStack, currentDeltaY, getOffset ]);
|
||||||
|
|
||||||
const update = useCallback((time: number) =>
|
const update = useCallback((time: number) =>
|
||||||
@ -106,10 +119,37 @@ export const ContextMenuView: FC<ContextMenuViewProps> = props =>
|
|||||||
updatePosition(bounds, location);
|
updatePosition(bounds, location);
|
||||||
}, [ objectId, category, updateFade, updatePosition ]);
|
}, [ objectId, category, updateFade, updatePosition ]);
|
||||||
|
|
||||||
|
const getClassNames = useMemo(() =>
|
||||||
|
{
|
||||||
|
const newClassNames: string[] = [ 'nitro-context-menu' ];
|
||||||
|
|
||||||
|
newClassNames.push((pos.x !== null) ? 'visible' : 'invisible');
|
||||||
|
|
||||||
|
if(classNames.length) newClassNames.push(...classNames);
|
||||||
|
|
||||||
|
return newClassNames;
|
||||||
|
}, [ pos, classNames ]);
|
||||||
|
|
||||||
|
const getStyle = useMemo(() =>
|
||||||
|
{
|
||||||
|
let newStyle: CSSProperties = {};
|
||||||
|
|
||||||
|
newStyle.left = (pos.x || 0);
|
||||||
|
newStyle.top = (pos.y || 0);
|
||||||
|
newStyle.opacity = opacity;
|
||||||
|
|
||||||
|
if(Object.keys(style).length) newStyle = { ...newStyle, ...style };
|
||||||
|
|
||||||
|
return newStyle;
|
||||||
|
}, [ pos, opacity, style ]);
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
BatchUpdates(() =>
|
||||||
{
|
{
|
||||||
setDeltaYStack(new FixedSizeStack(LOCATION_STACK_SIZE));
|
setDeltaYStack(new FixedSizeStack(LOCATION_STACK_SIZE));
|
||||||
setCurrentDeltaY(-1000000);
|
setCurrentDeltaY(-1000000);
|
||||||
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
@ -135,15 +175,8 @@ export const ContextMenuView: FC<ContextMenuViewProps> = props =>
|
|||||||
|
|
||||||
const timeout = setTimeout(() => setIsFading(true), fadeDelay);
|
const timeout = setTimeout(() => setIsFading(true), fadeDelay);
|
||||||
|
|
||||||
return () =>
|
return () => clearTimeout(timeout);
|
||||||
{
|
|
||||||
clearTimeout(timeout);
|
|
||||||
}
|
|
||||||
}, [ fades ]);
|
}, [ fades ]);
|
||||||
|
|
||||||
return (
|
return <Base innerRef={ elementRef } position={ position } classNames={ getClassNames } style={ getStyle } { ...rest } />;
|
||||||
<div ref={ elementRef } className={ `position-absolute nitro-context-menu ${ className }${ (pos.x !== null ? ' visible' : ' invisible') }` } style={ { left: (pos.x || 0), top: (pos.y || 0), opacity: opacity } }>
|
|
||||||
{ children }
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
export interface ContextMenuViewProps
|
|
||||||
{
|
|
||||||
objectId: number;
|
|
||||||
category: number;
|
|
||||||
userType?: number;
|
|
||||||
fades?: boolean;
|
|
||||||
className?: string;
|
|
||||||
close: () => void;
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
import { FC } from 'react';
|
|
||||||
import { ContextMenuHeaderViewProps } from './ContextMenuHeaderView.types';
|
|
||||||
|
|
||||||
export const ContextMenuHeaderView: FC<ContextMenuHeaderViewProps> = props =>
|
|
||||||
{
|
|
||||||
const { className = null, onClick = null, children = null } = props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={ 'd-flex justify-content-center align-items-center menu-header p-1' + (className ? ' ' + className : '') } onClick={ onClick }>
|
|
||||||
{ children }
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
export interface ContextMenuHeaderViewProps
|
|
||||||
{
|
|
||||||
className?: string;
|
|
||||||
onClick?: (e) => void;
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
import { FC, MouseEvent, useCallback } from 'react';
|
|
||||||
import { ContextMenuListItemViewProps } from './ContextMenuListItemView.types';
|
|
||||||
|
|
||||||
export const ContextMenuListItemView: FC<ContextMenuListItemViewProps> = props =>
|
|
||||||
{
|
|
||||||
const { className = '', canSelect = true, onClick = null, children = null } = props;
|
|
||||||
|
|
||||||
const handleClick = useCallback((event: MouseEvent<HTMLDivElement>) =>
|
|
||||||
{
|
|
||||||
if(!canSelect) return;
|
|
||||||
|
|
||||||
onClick(event);
|
|
||||||
}, [ canSelect, onClick ]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={ `d-flex justify-content-center align-items-center w-100 menu-item list-item ${ !canSelect ? 'disabled ' : '' }${ className }` } onClick={ handleClick }>
|
|
||||||
{ children }
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
import { MouseEvent } from 'react';
|
|
||||||
|
|
||||||
export interface ContextMenuListItemViewProps
|
|
||||||
{
|
|
||||||
className?: string;
|
|
||||||
canSelect?: boolean;
|
|
||||||
onClick: (event: MouseEvent) => void;
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
import { FC } from 'react';
|
|
||||||
import { ContextMenuListViewProps } from './ContextMenuListView.types';
|
|
||||||
|
|
||||||
export const ContextMenuListView: FC<ContextMenuListViewProps> = props =>
|
|
||||||
{
|
|
||||||
const { columns = 1, children = null } = props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={ 'd-flex flex-column menu-list' }>
|
|
||||||
{ children }
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
export interface ContextMenuListViewProps
|
|
||||||
{
|
|
||||||
columns?: number;
|
|
||||||
}
|
|
29
src/views/room/widgets/doorbell/DoorbellWidgetItemView.tsx
Normal file
29
src/views/room/widgets/doorbell/DoorbellWidgetItemView.tsx
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
|
import { FC } from 'react';
|
||||||
|
import { Button, ButtonGroup, Flex, Text } from '../../../../common';
|
||||||
|
|
||||||
|
interface DoorbellWidgetItemViewProps
|
||||||
|
{
|
||||||
|
userName: string;
|
||||||
|
accept: () => void;
|
||||||
|
deny: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DoorbellWidgetItemView: FC<DoorbellWidgetItemViewProps> = props =>
|
||||||
|
{
|
||||||
|
const { userName = '', accept = null, deny = null } = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Flex alignItems="center" justifyContent="between">
|
||||||
|
<Text bold>{ userName }</Text>
|
||||||
|
<ButtonGroup>
|
||||||
|
<Button variant="success" onClick={ accept }>
|
||||||
|
<FontAwesomeIcon icon="check" />
|
||||||
|
</Button>
|
||||||
|
<Button variant="danger" onClick={ deny }>
|
||||||
|
<FontAwesomeIcon icon="times" />
|
||||||
|
</Button>
|
||||||
|
</ButtonGroup>
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
}
|
@ -1,22 +0,0 @@
|
|||||||
.nitro-widget-doorbell {
|
|
||||||
width: 250px;
|
|
||||||
|
|
||||||
.content-area {
|
|
||||||
min-height: 143px;
|
|
||||||
height: 143px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.doorbell-user-list {
|
|
||||||
|
|
||||||
.list-item {
|
|
||||||
background: $grid-active-bg-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
.col:nth-child(even) {
|
|
||||||
|
|
||||||
.list-item {
|
|
||||||
background: $white !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,9 +1,10 @@
|
|||||||
import { FC, useCallback, useState } from 'react';
|
import { FC, useCallback, useState } from 'react';
|
||||||
import { LocalizeText, RoomWidgetDoorbellEvent, RoomWidgetLetUserInMessage } from '../../../../api';
|
import { LocalizeText, RoomWidgetDoorbellEvent, RoomWidgetLetUserInMessage } from '../../../../api';
|
||||||
import { CreateEventDispatcherHook } from '../../../../hooks';
|
import { Column } from '../../../../common';
|
||||||
|
import { BatchUpdates, CreateEventDispatcherHook } from '../../../../hooks';
|
||||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout';
|
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout';
|
||||||
import { useRoomContext } from '../../context/RoomContext';
|
import { useRoomContext } from '../../context/RoomContext';
|
||||||
import { DoorbellWidgetItemView } from './doorbell-item/DoorbellWidgetItemView';
|
import { DoorbellWidgetItemView } from './DoorbellWidgetItemView';
|
||||||
|
|
||||||
export const DoorbellWidgetView: FC<{}> = props =>
|
export const DoorbellWidgetView: FC<{}> = props =>
|
||||||
{
|
{
|
||||||
@ -15,10 +16,11 @@ export const DoorbellWidgetView: FC<{}> = props =>
|
|||||||
{
|
{
|
||||||
if(users.indexOf(userName) >= 0) return;
|
if(users.indexOf(userName) >= 0) return;
|
||||||
|
|
||||||
const newUsers = [ ...users, userName ];
|
BatchUpdates(() =>
|
||||||
|
{
|
||||||
setUsers(newUsers);
|
setUsers([ ...users, userName ]);
|
||||||
setIsVisible(true);
|
setIsVisible(true);
|
||||||
|
});
|
||||||
}, [ users ]);
|
}, [ users ]);
|
||||||
|
|
||||||
const removeUser = useCallback((userName: string) =>
|
const removeUser = useCallback((userName: string) =>
|
||||||
@ -66,13 +68,10 @@ export const DoorbellWidgetView: FC<{}> = props =>
|
|||||||
return (
|
return (
|
||||||
<NitroCardView className="nitro-widget-doorbell" simple={ true }>
|
<NitroCardView className="nitro-widget-doorbell" simple={ true }>
|
||||||
<NitroCardHeaderView headerText={ LocalizeText('navigator.doorbell.title') } onCloseClick={ event => setIsVisible(false) } />
|
<NitroCardHeaderView headerText={ LocalizeText('navigator.doorbell.title') } onCloseClick={ event => setIsVisible(false) } />
|
||||||
<NitroCardContentView>
|
<NitroCardContentView overflow="hidden">
|
||||||
<div className="row row-cols-1 doorbell-user-list">
|
<Column overflow="auto">
|
||||||
{ (users.length > 0) && users.map(userName =>
|
{ users && (users.length > 0) && users.map(userName => <DoorbellWidgetItemView key={ userName } userName={ userName } accept={ () => answer(userName, true) } deny={ () => answer(userName, false) } />) }
|
||||||
{
|
</Column>
|
||||||
return <DoorbellWidgetItemView key={ userName } userName={ userName } accept={ () => answer(userName, true) } deny={ () => answer(userName, false) } />;
|
|
||||||
}) }
|
|
||||||
</div>
|
|
||||||
</NitroCardContentView>
|
</NitroCardContentView>
|
||||||
</NitroCardView>
|
</NitroCardView>
|
||||||
);
|
);
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
import { FC } from 'react';
|
|
||||||
import { DoorbellWidgetItemViewProps } from './DoorbellWidgetItemView.types';
|
|
||||||
|
|
||||||
export const DoorbellWidgetItemView: FC<DoorbellWidgetItemViewProps> = props =>
|
|
||||||
{
|
|
||||||
const { userName = '', accept = null, deny = null } = props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="d-flex col align-items-center justify-content-between">
|
|
||||||
<span className="fw-bold text-black">{ userName }</span>
|
|
||||||
<div>
|
|
||||||
<button type="button" className="btn btn-success btn-sm me-1" onClick={ accept }>
|
|
||||||
<i className="fas fa-check" />
|
|
||||||
</button>
|
|
||||||
<button type="button" className="btn btn-danger btn-sm" onClick={ deny }>
|
|
||||||
<i className="fas fa-times" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
export interface DoorbellWidgetItemViewProps
|
|
||||||
{
|
|
||||||
userName: string;
|
|
||||||
accept: () => void;
|
|
||||||
deny: () => void;
|
|
||||||
}
|
|
@ -1,47 +1,40 @@
|
|||||||
import { FC, useCallback } from 'react';
|
import { FC } from 'react';
|
||||||
import { LocalizeText, RoomWidgetFriendRequestMessage } from '../../../../api';
|
import { LocalizeText, RoomWidgetFriendRequestMessage } from '../../../../api';
|
||||||
import { NitroLayoutButton, NitroLayoutFlex, NitroLayoutFlexColumn } from '../../../../layout';
|
import { Base, Button, Column, Flex, Text } from '../../../../common';
|
||||||
import { NitroLayoutBase } from '../../../../layout/base';
|
|
||||||
import { useRoomContext } from '../../context/RoomContext';
|
import { useRoomContext } from '../../context/RoomContext';
|
||||||
import { UserLocationView } from '../user-location/UserLocationView';
|
import { UserLocationView } from '../user-location/UserLocationView';
|
||||||
import { FriendRequestDialogViewProps } from './FriendRequestDialogView.types';
|
|
||||||
|
interface FriendRequestDialogViewProps
|
||||||
|
{
|
||||||
|
requestId: number;
|
||||||
|
userId: number;
|
||||||
|
userName: string;
|
||||||
|
close: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
export const FriendRequestDialogView: FC<FriendRequestDialogViewProps> = props =>
|
export const FriendRequestDialogView: FC<FriendRequestDialogViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { requestId = -1, userId = -1, userName = null, close = null } = props;
|
const { requestId = -1, userId = -1, userName = null, close = null } = props;
|
||||||
const { widgetHandler = null } = useRoomContext();
|
const { widgetHandler = null } = useRoomContext();
|
||||||
|
|
||||||
const accept = useCallback(() =>
|
const respond = (flag: boolean) =>
|
||||||
{
|
{
|
||||||
widgetHandler.processWidgetMessage(new RoomWidgetFriendRequestMessage(RoomWidgetFriendRequestMessage.ACCEPT, requestId));
|
widgetHandler.processWidgetMessage(new RoomWidgetFriendRequestMessage((flag ? RoomWidgetFriendRequestMessage.ACCEPT : RoomWidgetFriendRequestMessage.DECLINE), requestId));
|
||||||
|
|
||||||
close();
|
close();
|
||||||
}, [ requestId, widgetHandler, close ]);
|
}
|
||||||
|
|
||||||
const decline = useCallback(() =>
|
|
||||||
{
|
|
||||||
widgetHandler.processWidgetMessage(new RoomWidgetFriendRequestMessage(RoomWidgetFriendRequestMessage.ACCEPT, requestId));
|
|
||||||
|
|
||||||
close();
|
|
||||||
}, [ requestId, widgetHandler, close ]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<UserLocationView userId={ userId }>
|
<UserLocationView userId={ userId }>
|
||||||
<NitroLayoutBase className="nitro-friend-request-dialog nitro-context-menu p-2">
|
<Base className="nitro-friend-request-dialog nitro-context-menu p-2">
|
||||||
<NitroLayoutFlexColumn>
|
<Column>
|
||||||
<NitroLayoutBase className="h6">
|
<Text variant="white" fontSize={ 6 }>{ LocalizeText('widget.friendrequest.from', [ 'username' ], [ userName ]) }</Text>
|
||||||
{ LocalizeText('widget.friendrequest.from', [ 'username' ], [ userName ]) }
|
<Flex justifyContent="end" gap={ 1 }>
|
||||||
</NitroLayoutBase>
|
<Button variant="danger" onClick={ event => respond(false) }>{ LocalizeText('widget.friendrequest.decline') }</Button>
|
||||||
<NitroLayoutFlex className="justify-content-end align-items-center" gap={ 2 }>
|
<Button variant="success" onClick={ event => respond(true) }>{ LocalizeText('widget.friendrequest.accept') }</Button>
|
||||||
<NitroLayoutButton variant="danger" size="sm" onClick={ decline }>
|
</Flex>
|
||||||
{ LocalizeText('widget.friendrequest.decline') }
|
</Column>
|
||||||
</NitroLayoutButton>
|
</Base>
|
||||||
<NitroLayoutButton variant="success" size="sm" onClick={ accept }>
|
|
||||||
{ LocalizeText('widget.friendrequest.accept') }
|
|
||||||
</NitroLayoutButton>
|
|
||||||
</NitroLayoutFlex>
|
|
||||||
</NitroLayoutFlexColumn>
|
|
||||||
</NitroLayoutBase>
|
|
||||||
</UserLocationView>
|
</UserLocationView>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
export interface FriendRequestDialogViewProps
|
|
||||||
{
|
|
||||||
requestId: number;
|
|
||||||
userId: number;
|
|
||||||
userName: string;
|
|
||||||
close: () => void;
|
|
||||||
}
|
|
@ -38,7 +38,7 @@ export const FriendRequestWidgetView: FC<{}> = props =>
|
|||||||
newValue.splice(index, 1);
|
newValue.splice(index, 1);
|
||||||
|
|
||||||
return newValue;
|
return newValue;
|
||||||
})
|
});
|
||||||
}, [ friendRequests ]);
|
}, [ friendRequests ]);
|
||||||
|
|
||||||
const onRoomWidgetUpdateFriendRequestEvent = useCallback((event: RoomWidgetUpdateFriendRequestEvent) =>
|
const onRoomWidgetUpdateFriendRequestEvent = useCallback((event: RoomWidgetUpdateFriendRequestEvent) =>
|
||||||
|
@ -2,15 +2,69 @@
|
|||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@import './custom-stack-height/FurnitureCustomStackHeightView';
|
.nitro-widget-custom-stack-height {
|
||||||
|
width: $nitro-widget-custom-stack-height-width;
|
||||||
|
height: $nitro-widget-custom-stack-height-height;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nitro-room-widget-dimmer {
|
||||||
|
width: 275px;
|
||||||
|
|
||||||
|
.dimmer-banner {
|
||||||
|
width: 56px;
|
||||||
|
height: 79px;
|
||||||
|
background: url('../../../../assets/images/room-widgets/dimmer-widget/dimmer_banner.png') center no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.color-swatch {
|
||||||
|
height: 30px;
|
||||||
|
border: 2px solid $white;
|
||||||
|
box-shadow: inset 3px 3px rgba(0, 0, 0, .2);
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nitro-widget-exchange-credit {
|
||||||
|
width: $nitro-widget-exchange-credit-width;
|
||||||
|
height: $nitro-widget-exchange-credit-height;
|
||||||
|
|
||||||
|
.exchange-image {
|
||||||
|
background-image: url('../../../../assets/images/room-widgets/exchange-credit/exchange-credit-image.png');
|
||||||
|
width: 103px;
|
||||||
|
height: 103px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nitro-external-image-widget {
|
||||||
|
|
||||||
|
.picture-preview {
|
||||||
|
width: 320px;
|
||||||
|
height: 320px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nitro-gift-opening {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.nitro-mannequin {
|
||||||
|
}
|
||||||
|
|
||||||
|
.mannequin-preview {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 83px;
|
||||||
|
height: 130px;
|
||||||
|
background-image: url('../../../../assets/images/room-widgets/mannequin-widget/mannequin-spritesheet.png');
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
@import './dimmer/FurnitureDimmerView';
|
|
||||||
@import './exchange-credit/FurnitureExchangeCreditView';
|
|
||||||
@import './external-image/FurnitureExternalImageView';
|
|
||||||
@import './friend-furni/FurnitureFriendFurniView';
|
@import './friend-furni/FurnitureFriendFurniView';
|
||||||
@import './manipulation-menu/FurnitureManipulationMenuView';
|
@import './manipulation-menu/FurnitureManipulationMenuView';
|
||||||
@import './mannequin/FurnitureMannequinView';
|
|
||||||
@import './stickie/FurnitureStickieView';
|
@import './stickie/FurnitureStickieView';
|
||||||
@import './high-score/FurnitureHighScoreView';
|
@import './high-score/FurnitureHighScoreView';
|
||||||
@import './gift-opening/FurnitureGiftOpeningView';
|
|
||||||
@import './youtube-tv/FurnitureYoutubeDisplayView';
|
@import './youtube-tv/FurnitureYoutubeDisplayView';
|
||||||
|
@ -2,11 +2,8 @@ import { ApplyTonerComposer, RoomControllerLevel, RoomEngineObjectEvent, RoomEng
|
|||||||
import { FC, useCallback, useEffect, useState } from 'react';
|
import { FC, useCallback, useEffect, useState } from 'react';
|
||||||
import ReactSlider from 'react-slider';
|
import ReactSlider from 'react-slider';
|
||||||
import { GetRoomEngine, GetSessionDataManager, LocalizeText, RoomWidgetUpdateBackgroundColorPreviewEvent, RoomWidgetUpdateRoomObjectEvent } from '../../../../../api';
|
import { GetRoomEngine, GetSessionDataManager, LocalizeText, RoomWidgetUpdateBackgroundColorPreviewEvent, RoomWidgetUpdateRoomObjectEvent } from '../../../../../api';
|
||||||
import { Button } from '../../../../../common/Button';
|
import { Button, Column, Text } from '../../../../../common';
|
||||||
import { Column } from '../../../../../common/Column';
|
import { BatchUpdates, SendMessageHook } from '../../../../../hooks';
|
||||||
import { FormGroup } from '../../../../../common/FormGroup';
|
|
||||||
import { Text } from '../../../../../common/Text';
|
|
||||||
import { SendMessageHook } from '../../../../../hooks';
|
|
||||||
import { CreateEventDispatcherHook, useRoomEngineEvent } from '../../../../../hooks/events';
|
import { CreateEventDispatcherHook, useRoomEngineEvent } from '../../../../../hooks/events';
|
||||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout';
|
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout';
|
||||||
import { useRoomContext } from '../../../context/RoomContext';
|
import { useRoomContext } from '../../../context/RoomContext';
|
||||||
@ -45,10 +42,13 @@ export const FurnitureBackgroundColorView: FC<{}> = props =>
|
|||||||
const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category);
|
const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category);
|
||||||
const model = roomObject.model;
|
const model = roomObject.model;
|
||||||
|
|
||||||
|
BatchUpdates(() =>
|
||||||
|
{
|
||||||
setObjectId(roomObject.id);
|
setObjectId(roomObject.id);
|
||||||
setHue(parseInt(model.getValue<string>(RoomObjectVariable.FURNITURE_ROOM_BACKGROUND_COLOR_HUE)));
|
setHue(parseInt(model.getValue<string>(RoomObjectVariable.FURNITURE_ROOM_BACKGROUND_COLOR_HUE)));
|
||||||
setSaturation(parseInt(model.getValue<string>(RoomObjectVariable.FURNITURE_ROOM_BACKGROUND_COLOR_SATURATION)));
|
setSaturation(parseInt(model.getValue<string>(RoomObjectVariable.FURNITURE_ROOM_BACKGROUND_COLOR_SATURATION)));
|
||||||
setLightness(parseInt(model.getValue<string>(RoomObjectVariable.FURNITURE_ROOM_BACKGROUND_COLOR_LIGHTNESS)));
|
setLightness(parseInt(model.getValue<string>(RoomObjectVariable.FURNITURE_ROOM_BACKGROUND_COLOR_LIGHTNESS)));
|
||||||
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -89,10 +89,10 @@ export const FurnitureBackgroundColorView: FC<{}> = props =>
|
|||||||
return (
|
return (
|
||||||
<NitroCardView>
|
<NitroCardView>
|
||||||
<NitroCardHeaderView headerText={ LocalizeText('widget.backgroundcolor.title') } onCloseClick={ close } />
|
<NitroCardHeaderView headerText={ LocalizeText('widget.backgroundcolor.title') } onCloseClick={ close } />
|
||||||
<NitroCardContentView>
|
<NitroCardContentView overflow="hidden" justifyContent="between">
|
||||||
<Column overflow="auto">
|
<Column overflow="auto" gap={ 1 }>
|
||||||
<FormGroup column>
|
<Column>
|
||||||
<Text fontWeight="bold">{ LocalizeText('widget.backgroundcolor.hue') }</Text>
|
<Text bold>{ LocalizeText('widget.backgroundcolor.hue') }</Text>
|
||||||
<ReactSlider
|
<ReactSlider
|
||||||
className={ 'nitro-slider' }
|
className={ 'nitro-slider' }
|
||||||
min={ 0 }
|
min={ 0 }
|
||||||
@ -101,9 +101,9 @@ export const FurnitureBackgroundColorView: FC<{}> = props =>
|
|||||||
onChange={ event => setHue(event) }
|
onChange={ event => setHue(event) }
|
||||||
thumbClassName={ 'thumb degree' }
|
thumbClassName={ 'thumb degree' }
|
||||||
renderThumb={ (props, state) => <div { ...props }>{ state.valueNow }</div> } />
|
renderThumb={ (props, state) => <div { ...props }>{ state.valueNow }</div> } />
|
||||||
</FormGroup>
|
</Column>
|
||||||
<FormGroup column>
|
<Column>
|
||||||
<Text fontWeight="bold">{ LocalizeText('widget.backgroundcolor.saturation') }</Text>
|
<Text bold>{ LocalizeText('widget.backgroundcolor.saturation') }</Text>
|
||||||
<ReactSlider
|
<ReactSlider
|
||||||
className={ 'nitro-slider' }
|
className={ 'nitro-slider' }
|
||||||
min={ 0 }
|
min={ 0 }
|
||||||
@ -112,9 +112,9 @@ export const FurnitureBackgroundColorView: FC<{}> = props =>
|
|||||||
onChange={ event => setSaturation(event) }
|
onChange={ event => setSaturation(event) }
|
||||||
thumbClassName={ 'thumb percent' }
|
thumbClassName={ 'thumb percent' }
|
||||||
renderThumb={ (props, state) => <div { ...props }>{ state.valueNow }</div> } />
|
renderThumb={ (props, state) => <div { ...props }>{ state.valueNow }</div> } />
|
||||||
</FormGroup>
|
</Column>
|
||||||
<FormGroup column>
|
<Column>
|
||||||
<Text fontWeight="bold">{ LocalizeText('widget.backgroundcolor.lightness') }</Text>
|
<Text bold>{ LocalizeText('widget.backgroundcolor.lightness') }</Text>
|
||||||
<ReactSlider
|
<ReactSlider
|
||||||
className={ 'nitro-slider' }
|
className={ 'nitro-slider' }
|
||||||
min={ 0 }
|
min={ 0 }
|
||||||
@ -123,13 +123,13 @@ export const FurnitureBackgroundColorView: FC<{}> = props =>
|
|||||||
onChange={ event => setLightness(event) }
|
onChange={ event => setLightness(event) }
|
||||||
thumbClassName={ 'thumb percent' }
|
thumbClassName={ 'thumb percent' }
|
||||||
renderThumb={ (props, state) => <div { ...props }>{ state.valueNow }</div> } />
|
renderThumb={ (props, state) => <div { ...props }>{ state.valueNow }</div> } />
|
||||||
</FormGroup>
|
|
||||||
</Column>
|
</Column>
|
||||||
<Column center gap={ 1 }>
|
</Column>
|
||||||
<Button fullWidth variant="primary" size="sm" onClick={ event => processAction('toggle') }>
|
<Column gap={ 1 }>
|
||||||
|
<Button fullWidth variant="primary" onClick={ event => processAction('toggle') }>
|
||||||
{ LocalizeText('widget.backgroundcolor.button.on') }
|
{ LocalizeText('widget.backgroundcolor.button.on') }
|
||||||
</Button>
|
</Button>
|
||||||
<Button fullWidth variant="primary" size="sm" onClick={ event => processAction('apply') }>
|
<Button fullWidth variant="primary" onClick={ event => processAction('apply') }>
|
||||||
{ LocalizeText('widget.backgroundcolor.button.apply') }
|
{ LocalizeText('widget.backgroundcolor.button.apply') }
|
||||||
</Button>
|
</Button>
|
||||||
</Column>
|
</Column>
|
||||||
|
@ -9,8 +9,8 @@ import { FurnitureTrophyData } from '../trophy/FurnitureTrophyData';
|
|||||||
|
|
||||||
export const FurnitureBadgeDisplayView: FC<{}> = props =>
|
export const FurnitureBadgeDisplayView: FC<{}> = props =>
|
||||||
{
|
{
|
||||||
const { eventDispatcher = null, widgetHandler = null } = useRoomContext();
|
|
||||||
const [ trophyData, setTrophyData ] = useState<FurnitureTrophyData>(null);
|
const [ trophyData, setTrophyData ] = useState<FurnitureTrophyData>(null);
|
||||||
|
const { widgetHandler = null } = useRoomContext();
|
||||||
|
|
||||||
const onNitroEvent = useCallback((event: NitroEvent) =>
|
const onNitroEvent = useCallback((event: NitroEvent) =>
|
||||||
{
|
{
|
||||||
|
@ -0,0 +1,41 @@
|
|||||||
|
import { FC } from 'react';
|
||||||
|
import { LocalizeText } from '../../../../../api';
|
||||||
|
import { Button, Column, Flex, Text } from '../../../../../common';
|
||||||
|
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout';
|
||||||
|
import { useRoomContext } from '../../../context/RoomContext';
|
||||||
|
|
||||||
|
interface EffectBoxConfirmViewProps
|
||||||
|
{
|
||||||
|
objectId: number;
|
||||||
|
close: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const EffectBoxConfirmView: FC<EffectBoxConfirmViewProps> = props =>
|
||||||
|
{
|
||||||
|
const { objectId = -1, close = null } = props;
|
||||||
|
const { roomSession = null } = useRoomContext();
|
||||||
|
|
||||||
|
const useProduct = () =>
|
||||||
|
{
|
||||||
|
roomSession.useMultistateItem(objectId);
|
||||||
|
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<NitroCardView className="nitro-use-product-confirmation">
|
||||||
|
<NitroCardHeaderView headerText={ LocalizeText('effectbox.header.title') } onCloseClick={ close } />
|
||||||
|
<NitroCardContentView center>
|
||||||
|
<Flex gap={ 2 }>
|
||||||
|
<Column justifyContent="between">
|
||||||
|
<Text>{ LocalizeText('effectbox.header.description') }</Text>
|
||||||
|
<Flex alignItems="center" justifyContent="between">
|
||||||
|
<Button variant="danger" onClick={ close }>{ LocalizeText('generic.cancel') }</Button>
|
||||||
|
<Button variant="success" onClick={ useProduct }>{ LocalizeText('generic.ok') }</Button>
|
||||||
|
</Flex>
|
||||||
|
</Column>
|
||||||
|
</Flex>
|
||||||
|
</NitroCardContentView>
|
||||||
|
</NitroCardView>
|
||||||
|
);
|
||||||
|
}
|
@ -3,15 +3,15 @@ import { GroupFurniContextMenuInfoMessageEvent } from '@nitrots/nitro-renderer/s
|
|||||||
import { FC, useCallback, useState } from 'react';
|
import { FC, useCallback, useState } from 'react';
|
||||||
import { GetGroupInformation, GetRoomEngine, IsOwnerOfFurniture, LocalizeText, RoomWidgetFurniActionMessage, TryVisitRoom } from '../../../../../api';
|
import { GetGroupInformation, GetRoomEngine, IsOwnerOfFurniture, LocalizeText, RoomWidgetFurniActionMessage, TryVisitRoom } from '../../../../../api';
|
||||||
import { TryJoinGroup } from '../../../../../api/groups/TryJoinGroup';
|
import { TryJoinGroup } from '../../../../../api/groups/TryJoinGroup';
|
||||||
import { CreateMessageHook } from '../../../../../hooks';
|
import { BatchUpdates, CreateMessageHook } from '../../../../../hooks';
|
||||||
import { useRoomEngineEvent } from '../../../../../hooks/events';
|
import { useRoomEngineEvent } from '../../../../../hooks/events';
|
||||||
import { useRoomContext } from '../../../context/RoomContext';
|
import { useRoomContext } from '../../../context/RoomContext';
|
||||||
|
import { ContextMenuHeaderView } from '../../context-menu/ContextMenuHeaderView';
|
||||||
|
import { ContextMenuListItemView } from '../../context-menu/ContextMenuListItemView';
|
||||||
import { ContextMenuView } from '../../context-menu/ContextMenuView';
|
import { ContextMenuView } from '../../context-menu/ContextMenuView';
|
||||||
import { ContextMenuHeaderView } from '../../context-menu/views/header/ContextMenuHeaderView';
|
import { EffectBoxConfirmView } from './EffectBoxConfirmView';
|
||||||
import { ContextMenuListItemView } from '../../context-menu/views/list-item/ContextMenuListItemView';
|
import { MonsterPlantSeedConfirmView } from './MonsterPlantSeedConfirmView';
|
||||||
import { EffectBoxConfirmView } from './views/effect-box/EffectBoxConfirmView';
|
import { PurchasableClothingConfirmView } from './PurchasableClothingConfirmView';
|
||||||
import { MonsterPlantSeedConfirmView } from './views/monsterplant-seed/MonsterPlantSeedConfirmView';
|
|
||||||
import { PurchasableClothingConfirmView } from './views/purchaseable-clothing/PurchasableClothingConfirmView';
|
|
||||||
|
|
||||||
const MONSTERPLANT_SEED_CONFIRMATION: string = 'MONSTERPLANT_SEED_CONFIRMATION';
|
const MONSTERPLANT_SEED_CONFIRMATION: string = 'MONSTERPLANT_SEED_CONFIRMATION';
|
||||||
const PURCHASABLE_CLOTHING_CONFIRMATION: string = 'PURCHASABLE_CLOTHING_CONFIRMATION';
|
const PURCHASABLE_CLOTHING_CONFIRMATION: string = 'PURCHASABLE_CLOTHING_CONFIRMATION';
|
||||||
@ -26,22 +26,24 @@ export const FurnitureContextMenuView: FC<{}> = props =>
|
|||||||
const [ confirmingObjectId, setConfirmingObjectId ] = useState(-1);
|
const [ confirmingObjectId, setConfirmingObjectId ] = useState(-1);
|
||||||
const [ groupData, setGroupData ] = useState<GroupFurniContextMenuInfoMessageParser>(null);
|
const [ groupData, setGroupData ] = useState<GroupFurniContextMenuInfoMessageParser>(null);
|
||||||
const [ isGroupMember, setIsGroupMember ] = useState(false);
|
const [ isGroupMember, setIsGroupMember ] = useState(false);
|
||||||
|
|
||||||
const { roomSession = null, widgetHandler = null } = useRoomContext();
|
const { roomSession = null, widgetHandler = null } = useRoomContext();
|
||||||
|
|
||||||
const close = useCallback(() =>
|
const close = useCallback(() =>
|
||||||
|
{
|
||||||
|
BatchUpdates(() =>
|
||||||
{
|
{
|
||||||
setObjectId(-1);
|
setObjectId(-1);
|
||||||
setGroupData(null);
|
setGroupData(null);
|
||||||
setIsGroupMember(false);
|
setIsGroupMember(false);
|
||||||
setMode(null);
|
setMode(null);
|
||||||
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const closeConfirm = useCallback(() =>
|
const closeConfirm = () =>
|
||||||
{
|
{
|
||||||
setConfirmMode(null);
|
setConfirmMode(null);
|
||||||
setConfirmingObjectId(-1);
|
setConfirmingObjectId(-1);
|
||||||
}, []);
|
}
|
||||||
|
|
||||||
const onRoomEngineTriggerWidgetEvent = useCallback((event: RoomEngineTriggerWidgetEvent) =>
|
const onRoomEngineTriggerWidgetEvent = useCallback((event: RoomEngineTriggerWidgetEvent) =>
|
||||||
{
|
{
|
||||||
@ -54,28 +56,40 @@ export const FurnitureContextMenuView: FC<{}> = props =>
|
|||||||
case RoomEngineTriggerWidgetEvent.REQUEST_MONSTERPLANT_SEED_PLANT_CONFIRMATION_DIALOG:
|
case RoomEngineTriggerWidgetEvent.REQUEST_MONSTERPLANT_SEED_PLANT_CONFIRMATION_DIALOG:
|
||||||
if(!IsOwnerOfFurniture(object)) return;
|
if(!IsOwnerOfFurniture(object)) return;
|
||||||
|
|
||||||
|
BatchUpdates(() =>
|
||||||
|
{
|
||||||
setConfirmingObjectId(object.id);
|
setConfirmingObjectId(object.id);
|
||||||
setConfirmMode(MONSTERPLANT_SEED_CONFIRMATION);
|
setConfirmMode(MONSTERPLANT_SEED_CONFIRMATION);
|
||||||
|
});
|
||||||
|
|
||||||
close();
|
close();
|
||||||
return;
|
return;
|
||||||
case RoomEngineTriggerWidgetEvent.REQUEST_EFFECTBOX_OPEN_DIALOG:
|
case RoomEngineTriggerWidgetEvent.REQUEST_EFFECTBOX_OPEN_DIALOG:
|
||||||
if(!IsOwnerOfFurniture(object)) return;
|
if(!IsOwnerOfFurniture(object)) return;
|
||||||
|
|
||||||
|
BatchUpdates(() =>
|
||||||
|
{
|
||||||
setConfirmingObjectId(object.id);
|
setConfirmingObjectId(object.id);
|
||||||
setConfirmMode(EFFECTBOX_OPEN);
|
setConfirmMode(EFFECTBOX_OPEN);
|
||||||
|
});
|
||||||
|
|
||||||
close();
|
close();
|
||||||
return;
|
return;
|
||||||
case RoomEngineTriggerWidgetEvent.REQUEST_PURCHASABLE_CLOTHING_CONFIRMATION_DIALOG:
|
case RoomEngineTriggerWidgetEvent.REQUEST_PURCHASABLE_CLOTHING_CONFIRMATION_DIALOG:
|
||||||
if(!IsOwnerOfFurniture(object)) return;
|
if(!IsOwnerOfFurniture(object)) return;
|
||||||
|
|
||||||
|
BatchUpdates(() =>
|
||||||
|
{
|
||||||
setConfirmingObjectId(object.id);
|
setConfirmingObjectId(object.id);
|
||||||
setConfirmMode(PURCHASABLE_CLOTHING_CONFIRMATION);
|
setConfirmMode(PURCHASABLE_CLOTHING_CONFIRMATION);
|
||||||
|
});
|
||||||
|
|
||||||
close();
|
close();
|
||||||
return;
|
return;
|
||||||
case RoomEngineTriggerWidgetEvent.OPEN_FURNI_CONTEXT_MENU:
|
case RoomEngineTriggerWidgetEvent.OPEN_FURNI_CONTEXT_MENU:
|
||||||
|
|
||||||
|
BatchUpdates(() =>
|
||||||
|
{
|
||||||
setObjectId(object.id);
|
setObjectId(object.id);
|
||||||
|
|
||||||
switch(event.contextMenu)
|
switch(event.contextMenu)
|
||||||
@ -95,6 +109,7 @@ export const FurnitureContextMenuView: FC<{}> = props =>
|
|||||||
if(IsOwnerOfFurniture(object)) setMode(ContextMenuEnum.PURCHASABLE_CLOTHING);
|
if(IsOwnerOfFurniture(object)) setMode(ContextMenuEnum.PURCHASABLE_CLOTHING);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
case RoomEngineTriggerWidgetEvent.CLOSE_FURNI_CONTEXT_MENU:
|
case RoomEngineTriggerWidgetEvent.CLOSE_FURNI_CONTEXT_MENU:
|
||||||
@ -113,15 +128,18 @@ export const FurnitureContextMenuView: FC<{}> = props =>
|
|||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
BatchUpdates(() =>
|
||||||
|
{
|
||||||
setObjectId(parser.objectId);
|
setObjectId(parser.objectId);
|
||||||
setGroupData(parser);
|
setGroupData(parser);
|
||||||
setIsGroupMember(parser.userIsMember);
|
setIsGroupMember(parser.userIsMember);
|
||||||
setMode(GROUP_FURNITURE);
|
setMode(GROUP_FURNITURE);
|
||||||
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
CreateMessageHook(GroupFurniContextMenuInfoMessageEvent, onGroupFurniContextMenuInfoMessageEvent);
|
CreateMessageHook(GroupFurniContextMenuInfoMessageEvent, onGroupFurniContextMenuInfoMessageEvent);
|
||||||
|
|
||||||
const processAction = useCallback((name: string) =>
|
const processAction = (name: string) =>
|
||||||
{
|
{
|
||||||
if(name)
|
if(name)
|
||||||
{
|
{
|
||||||
@ -152,7 +170,7 @@ export const FurnitureContextMenuView: FC<{}> = props =>
|
|||||||
}
|
}
|
||||||
|
|
||||||
close();
|
close();
|
||||||
}, [ roomSession, widgetHandler, objectId, groupData, close ]);
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -1,10 +1,16 @@
|
|||||||
import { IFurnitureData, RoomObjectCategory } from '@nitrots/nitro-renderer';
|
import { IFurnitureData, RoomObjectCategory } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback, useEffect, useState } from 'react';
|
import { FC, useEffect, useState } from 'react';
|
||||||
import { GetFurnitureDataForRoomObject, LocalizeText, RoomWidgetUseProductMessage } from '../../../../../../../api';
|
import { GetFurnitureDataForRoomObject, LocalizeText, RoomWidgetUseProductMessage } from '../../../../../api';
|
||||||
import { FurniCategory } from '../../../../../../../components/inventory/common/FurniCategory';
|
import { Base, Button, Column, Flex, Text } from '../../../../../common';
|
||||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../../../layout';
|
import { FurniCategory } from '../../../../../components/inventory/common/FurniCategory';
|
||||||
import { useRoomContext } from '../../../../../context/RoomContext';
|
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout';
|
||||||
import { MonsterPlantSeedConfirmViewProps } from './MonsterPlantSeedConfirmView.types';
|
import { useRoomContext } from '../../../context/RoomContext';
|
||||||
|
|
||||||
|
interface MonsterPlantSeedConfirmViewProps
|
||||||
|
{
|
||||||
|
objectId: number;
|
||||||
|
close: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
const MODE_DEFAULT: number = -1;
|
const MODE_DEFAULT: number = -1;
|
||||||
const MODE_MONSTERPLANT_SEED: number = 0;
|
const MODE_MONSTERPLANT_SEED: number = 0;
|
||||||
@ -16,12 +22,12 @@ export const MonsterPlantSeedConfirmView: FC<MonsterPlantSeedConfirmViewProps> =
|
|||||||
const [ mode, setMode ] = useState(MODE_DEFAULT);
|
const [ mode, setMode ] = useState(MODE_DEFAULT);
|
||||||
const { roomSession = null, widgetHandler = null } = useRoomContext();
|
const { roomSession = null, widgetHandler = null } = useRoomContext();
|
||||||
|
|
||||||
const useProduct = useCallback(() =>
|
const useProduct = () =>
|
||||||
{
|
{
|
||||||
widgetHandler.processWidgetMessage(new RoomWidgetUseProductMessage(RoomWidgetUseProductMessage.MONSTERPLANT_SEED, objectId));
|
widgetHandler.processWidgetMessage(new RoomWidgetUseProductMessage(RoomWidgetUseProductMessage.MONSTERPLANT_SEED, objectId));
|
||||||
|
|
||||||
close();
|
close();
|
||||||
}, [ widgetHandler, objectId, close ]);
|
}
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
@ -57,24 +63,24 @@ export const MonsterPlantSeedConfirmView: FC<MonsterPlantSeedConfirmViewProps> =
|
|||||||
return (
|
return (
|
||||||
<NitroCardView className="nitro-use-product-confirmation">
|
<NitroCardView className="nitro-use-product-confirmation">
|
||||||
<NitroCardHeaderView headerText={ LocalizeText('useproduct.widget.title.plant_seed', [ 'name' ], [ furniData.name ]) } onCloseClick={ close } />
|
<NitroCardHeaderView headerText={ LocalizeText('useproduct.widget.title.plant_seed', [ 'name' ], [ furniData.name ]) } onCloseClick={ close } />
|
||||||
<NitroCardContentView className="d-flex">
|
<NitroCardContentView center>
|
||||||
<div className="row">
|
<Flex gap={ 2 } overflow="hidden">
|
||||||
<div className="w-unset">
|
<Column>
|
||||||
<div className="product-preview">
|
<Base className="product-preview">
|
||||||
<div className="monsterplant-image" />
|
<Base className="monsterplant-image" />
|
||||||
</div>
|
</Base>
|
||||||
</div>
|
</Column>
|
||||||
<div className="col d-flex flex-column justify-content-between">
|
<Column justifyContent="between" overflow="auto">
|
||||||
<div className="d-flex flex-column">
|
<Column gap={ 2 }>
|
||||||
<div className="text-black mb-3">{ LocalizeText('useproduct.widget.text.plant_seed', [ 'productName' ], [ furniData.name ] ) }</div>
|
<Text>{ LocalizeText('useproduct.widget.text.plant_seed', [ 'productName' ], [ furniData.name ] ) }</Text>
|
||||||
<div className="text-black">{ LocalizeText('useproduct.widget.info.plant_seed') }</div>
|
<Text>{ LocalizeText('useproduct.widget.info.plant_seed') }</Text>
|
||||||
</div>
|
</Column>
|
||||||
<div className="d-flex justify-content-between align-items-end w-100 h-100">
|
<Flex alignItems="center" justifyContent="between">
|
||||||
<button type="button" className="btn btn-danger" onClick={ close }>{ LocalizeText('useproduct.widget.cancel') }</button>
|
<Button variant="danger" onClick={ close }>{ LocalizeText('useproduct.widget.cancel') }</Button>
|
||||||
<button type="button" className="btn btn-primary" onClick={ useProduct }>{ LocalizeText('widget.monsterplant_seed.button.use') }</button>
|
<Button variant="success" onClick={ useProduct }>{ LocalizeText('widget.monsterplant_seed.button.use') }</Button>
|
||||||
</div>
|
</Flex>
|
||||||
</div>
|
</Column>
|
||||||
</div>
|
</Flex>
|
||||||
</NitroCardContentView>
|
</NitroCardContentView>
|
||||||
</NitroCardView>
|
</NitroCardView>
|
||||||
);
|
);
|
@ -1,12 +1,18 @@
|
|||||||
import { RedeemItemClothingComposer, RoomObjectCategory, UserFigureComposer } from '@nitrots/nitro-renderer';
|
import { RedeemItemClothingComposer, RoomObjectCategory, UserFigureComposer } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback, useEffect, useState } from 'react';
|
import { FC, useEffect, useState } from 'react';
|
||||||
import { GetAvatarRenderManager, GetConnection, GetFurnitureDataForRoomObject, GetSessionDataManager, LocalizeText } from '../../../../../../../api';
|
import { GetAvatarRenderManager, GetConnection, GetFurnitureDataForRoomObject, GetSessionDataManager, LocalizeText } from '../../../../../api';
|
||||||
import { FigureData } from '../../../../../../../components/avatar-editor/common/FigureData';
|
import { Base, Button, Column, Flex, Text } from '../../../../../common';
|
||||||
import { FurniCategory } from '../../../../../../../components/inventory/common/FurniCategory';
|
import { FigureData } from '../../../../../components/avatar-editor/common/FigureData';
|
||||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../../../layout';
|
import { FurniCategory } from '../../../../../components/inventory/common/FurniCategory';
|
||||||
import { AvatarImageView } from '../../../../../../shared/avatar-image/AvatarImageView';
|
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout';
|
||||||
import { useRoomContext } from '../../../../../context/RoomContext';
|
import { AvatarImageView } from '../../../../shared/avatar-image/AvatarImageView';
|
||||||
import { PurchasableClothingConfirmViewProps } from './PurchasableClothingConfirmView.types';
|
import { useRoomContext } from '../../../context/RoomContext';
|
||||||
|
|
||||||
|
interface PurchasableClothingConfirmViewProps
|
||||||
|
{
|
||||||
|
objectId: number;
|
||||||
|
close: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
const MODE_DEFAULT: number = -1;
|
const MODE_DEFAULT: number = -1;
|
||||||
const MODE_PURCHASABLE_CLOTHING: number = 0;
|
const MODE_PURCHASABLE_CLOTHING: number = 0;
|
||||||
@ -19,13 +25,13 @@ export const PurchasableClothingConfirmView: FC<PurchasableClothingConfirmViewPr
|
|||||||
const [ newFigure, setNewFigure ] = useState<string>(null);
|
const [ newFigure, setNewFigure ] = useState<string>(null);
|
||||||
const { roomSession = null } = useRoomContext();
|
const { roomSession = null } = useRoomContext();
|
||||||
|
|
||||||
const useProduct = useCallback(() =>
|
const useProduct = () =>
|
||||||
{
|
{
|
||||||
GetConnection().send(new RedeemItemClothingComposer(objectId));
|
GetConnection().send(new RedeemItemClothingComposer(objectId));
|
||||||
GetConnection().send(new UserFigureComposer(gender, newFigure));
|
GetConnection().send(new UserFigureComposer(gender, newFigure));
|
||||||
|
|
||||||
close();
|
close();
|
||||||
}, [ objectId, gender, newFigure, close ]);
|
}
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
@ -78,24 +84,24 @@ export const PurchasableClothingConfirmView: FC<PurchasableClothingConfirmViewPr
|
|||||||
return (
|
return (
|
||||||
<NitroCardView className="nitro-use-product-confirmation">
|
<NitroCardView className="nitro-use-product-confirmation">
|
||||||
<NitroCardHeaderView headerText={ LocalizeText('useproduct.widget.title.bind_clothing') } onCloseClick={ close } />
|
<NitroCardHeaderView headerText={ LocalizeText('useproduct.widget.title.bind_clothing') } onCloseClick={ close } />
|
||||||
<NitroCardContentView className="d-flex">
|
<NitroCardContentView center>
|
||||||
<div className="row">
|
<Flex gap={ 2 } overflow="hidden">
|
||||||
<div className="w-unset">
|
<Column>
|
||||||
<div className="mannequin-preview">
|
<Base className="mannequin-preview">
|
||||||
<AvatarImageView figure={ newFigure } direction={ 2 } />
|
<AvatarImageView figure={ newFigure } direction={ 2 } />
|
||||||
</div>
|
</Base>
|
||||||
</div>
|
</Column>
|
||||||
<div className="col d-flex flex-column justify-content-between">
|
<Column justifyContent="between" overflow="auto">
|
||||||
<div className="d-flex flex-column">
|
<Column gap={ 2 }>
|
||||||
<div className="text-black mb-3">{ LocalizeText('useproduct.widget.text.bind_clothing') }</div>
|
<Text>{ LocalizeText('useproduct.widget.text.bind_clothing') }</Text>
|
||||||
<div className="text-black">{ LocalizeText('useproduct.widget.info.bind_clothing') }</div>
|
<Text>{ LocalizeText('useproduct.widget.info.bind_clothing') }</Text>
|
||||||
</div>
|
</Column>
|
||||||
<div className="d-flex justify-content-between align-items-end w-100 h-100">
|
<Flex alignItems="center" justifyContent="between">
|
||||||
<button type="button" className="btn btn-danger" onClick={ close }>{ LocalizeText('useproduct.widget.cancel') }</button>
|
<Button variant="danger" onClick={ close }>{ LocalizeText('useproduct.widget.cancel') }</Button>
|
||||||
<button type="button" className="btn btn-primary" onClick={ useProduct }>{ LocalizeText('useproduct.widget.bind_clothing') }</button>
|
<Button variant="success" onClick={ useProduct }>{ LocalizeText('useproduct.widget.bind_clothing') }</Button>
|
||||||
</div>
|
</Flex>
|
||||||
</div>
|
</Column>
|
||||||
</div>
|
</Flex>
|
||||||
</NitroCardContentView>
|
</NitroCardContentView>
|
||||||
</NitroCardView>
|
</NitroCardView>
|
||||||
);
|
);
|
@ -1,37 +0,0 @@
|
|||||||
import { FC, useCallback } from 'react';
|
|
||||||
import { LocalizeText } from '../../../../../../../api';
|
|
||||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../../../layout';
|
|
||||||
import { useRoomContext } from '../../../../../context/RoomContext';
|
|
||||||
import { EffectBoxConfirmViewProps } from './EffectBoxConfirmView.types';
|
|
||||||
|
|
||||||
export const EffectBoxConfirmView: FC<EffectBoxConfirmViewProps> = props =>
|
|
||||||
{
|
|
||||||
const { objectId = -1, close = null } = props;
|
|
||||||
const { roomSession = null, widgetHandler = null } = useRoomContext();
|
|
||||||
|
|
||||||
const useProduct = useCallback(() =>
|
|
||||||
{
|
|
||||||
roomSession.useMultistateItem(objectId);
|
|
||||||
|
|
||||||
close();
|
|
||||||
}, [ roomSession, objectId, close ]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<NitroCardView className="nitro-use-product-confirmation">
|
|
||||||
<NitroCardHeaderView headerText={ LocalizeText('effectbox.header.title') } onCloseClick={ close } />
|
|
||||||
<NitroCardContentView className="d-flex">
|
|
||||||
<div className="row">
|
|
||||||
<div className="col d-flex flex-column justify-content-between">
|
|
||||||
<div className="d-flex flex-column">
|
|
||||||
<div className="text-black">{ LocalizeText('effectbox.header.description') }</div>
|
|
||||||
</div>
|
|
||||||
<div className="d-flex justify-content-between align-items-end w-100 h-100">
|
|
||||||
<button type="button" className="btn btn-danger" onClick={ close }>{ LocalizeText('generic.cancel') }</button>
|
|
||||||
<button type="button" className="btn btn-primary" onClick={ useProduct }>{ LocalizeText('generic.ok') }</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</NitroCardContentView>
|
|
||||||
</NitroCardView>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
export interface EffectBoxConfirmViewProps
|
|
||||||
{
|
|
||||||
objectId: number;
|
|
||||||
close: () => void;
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
export interface MonsterPlantSeedConfirmViewProps
|
|
||||||
{
|
|
||||||
objectId: number;
|
|
||||||
close: () => void;
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
export interface PurchasableClothingConfirmViewProps
|
|
||||||
{
|
|
||||||
objectId: number;
|
|
||||||
close: () => void;
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
.nitro-widget-custom-stack-height {
|
|
||||||
width: $nitro-widget-custom-stack-height-width;
|
|
||||||
height: $nitro-widget-custom-stack-height-height;
|
|
||||||
}
|
|
@ -2,10 +2,10 @@ import { FurnitureStackHeightComposer, FurnitureStackHeightEvent } from '@nitrot
|
|||||||
import { FC, useCallback, useEffect, useState } from 'react';
|
import { FC, useCallback, useEffect, useState } from 'react';
|
||||||
import ReactSlider from 'react-slider';
|
import ReactSlider from 'react-slider';
|
||||||
import { LocalizeText, RoomWidgetUpdateCustomStackHeightEvent } from '../../../../../api';
|
import { LocalizeText, RoomWidgetUpdateCustomStackHeightEvent } from '../../../../../api';
|
||||||
|
import { Button, Column, Flex, Text } from '../../../../../common';
|
||||||
import { BatchUpdates, CreateMessageHook, SendMessageHook } from '../../../../../hooks';
|
import { BatchUpdates, CreateMessageHook, SendMessageHook } from '../../../../../hooks';
|
||||||
import { CreateEventDispatcherHook } from '../../../../../hooks/events';
|
import { CreateEventDispatcherHook } from '../../../../../hooks/events';
|
||||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView, NitroLayoutButton, NitroLayoutFlex, NitroLayoutFlexColumn, NitroLayoutGrid, NitroLayoutGridColumn } from '../../../../../layout';
|
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout';
|
||||||
import { NitroLayoutBase } from '../../../../../layout/base';
|
|
||||||
import { useRoomContext } from '../../../context/RoomContext';
|
import { useRoomContext } from '../../../context/RoomContext';
|
||||||
|
|
||||||
const MAX_HEIGHT: number = 40;
|
const MAX_HEIGHT: number = 40;
|
||||||
@ -17,14 +17,14 @@ export const FurnitureCustomStackHeightView: FC<{}> = props =>
|
|||||||
const [ pendingHeight, setPendingHeight ] = useState(-1);
|
const [ pendingHeight, setPendingHeight ] = useState(-1);
|
||||||
const { eventDispatcher = null } = useRoomContext();
|
const { eventDispatcher = null } = useRoomContext();
|
||||||
|
|
||||||
const close = useCallback(() =>
|
const close = () =>
|
||||||
{
|
{
|
||||||
BatchUpdates(() =>
|
BatchUpdates(() =>
|
||||||
{
|
{
|
||||||
setObjectId(-1);
|
setObjectId(-1);
|
||||||
setHeight(0);
|
setHeight(0);
|
||||||
});
|
});
|
||||||
}, []);
|
}
|
||||||
|
|
||||||
const updateHeight = useCallback((height: number, fromServer: boolean = false) =>
|
const updateHeight = useCallback((height: number, fromServer: boolean = false) =>
|
||||||
{
|
{
|
||||||
@ -83,16 +83,11 @@ export const FurnitureCustomStackHeightView: FC<{}> = props =>
|
|||||||
if(objectId === -1) return null;
|
if(objectId === -1) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NitroCardView className="nitro-widget-custom-stack-height" simple={ true }>
|
<NitroCardView className="nitro-widget-custom-stack-height" simple>
|
||||||
<NitroCardHeaderView headerText={ LocalizeText('widget.custom.stack.height.title') } onCloseClick={ close } />
|
<NitroCardHeaderView headerText={ LocalizeText('widget.custom.stack.height.title') } onCloseClick={ close } />
|
||||||
<NitroCardContentView>
|
<NitroCardContentView justifyContent="between">
|
||||||
<NitroLayoutGrid>
|
<Text>{ LocalizeText('widget.custom.stack.height.text') }</Text>
|
||||||
<NitroLayoutGridColumn className="justify-content-between" size={ 12 }>
|
<Flex gap={ 2 }>
|
||||||
<NitroLayoutBase className="text-black" overflow="auto">
|
|
||||||
{ LocalizeText('widget.custom.stack.height.text') }
|
|
||||||
</NitroLayoutBase>
|
|
||||||
<NitroLayoutFlexColumn gap={ 2 }>
|
|
||||||
<NitroLayoutFlex gap={ 2 }>
|
|
||||||
<ReactSlider
|
<ReactSlider
|
||||||
className="nitro-slider"
|
className="nitro-slider"
|
||||||
min={ 0 }
|
min={ 0 }
|
||||||
@ -102,16 +97,15 @@ export const FurnitureCustomStackHeightView: FC<{}> = props =>
|
|||||||
onChange={ event => updateHeight(event) }
|
onChange={ event => updateHeight(event) }
|
||||||
renderThumb={ (props, state) => <div { ...props }>{ state.valueNow }</div> } />
|
renderThumb={ (props, state) => <div { ...props }>{ state.valueNow }</div> } />
|
||||||
<input type="number" min={ 0 } max={ MAX_HEIGHT } value={ height } onChange={ event => updateHeight(parseFloat(event.target.value)) } />
|
<input type="number" min={ 0 } max={ MAX_HEIGHT } value={ height } onChange={ event => updateHeight(parseFloat(event.target.value)) } />
|
||||||
</NitroLayoutFlex>
|
</Flex>
|
||||||
<NitroLayoutButton variant="primary" onClick={ event => sendUpdate(-100) }>
|
<Column gap={ 1 }>
|
||||||
|
<Button onClick={ event => sendUpdate(-100) }>
|
||||||
{ LocalizeText('furniture.above.stack') }
|
{ LocalizeText('furniture.above.stack') }
|
||||||
</NitroLayoutButton>
|
</Button>
|
||||||
<NitroLayoutButton variant="primary" onClick={ event => sendUpdate(0) }>
|
<Button onClick={ event => sendUpdate(0) }>
|
||||||
{ LocalizeText('furniture.floor.level') }
|
{ LocalizeText('furniture.floor.level') }
|
||||||
</NitroLayoutButton>
|
</Button>
|
||||||
</NitroLayoutFlexColumn>
|
</Column>
|
||||||
</NitroLayoutGridColumn>
|
|
||||||
</NitroLayoutGrid>
|
|
||||||
</NitroCardContentView>
|
</NitroCardContentView>
|
||||||
</NitroCardView>
|
</NitroCardView>
|
||||||
);
|
);
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
.nitro-dimmer {
|
|
||||||
width: 300px;
|
|
||||||
|
|
||||||
.dimmer-banner {
|
|
||||||
width: 56px;
|
|
||||||
height: 79px;
|
|
||||||
background: url(../../../../../assets/images/room-widgets/dimmer-widget/dimmer_banner.png) center no-repeat;
|
|
||||||
}
|
|
||||||
|
|
||||||
.color-swatch {
|
|
||||||
height: 30px;
|
|
||||||
border: 2px solid $white;
|
|
||||||
box-shadow: inset 3px 3px rgba(0, 0, 0, .2);
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,11 +3,7 @@ import classNames from 'classnames';
|
|||||||
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import ReactSlider from 'react-slider';
|
import ReactSlider from 'react-slider';
|
||||||
import { ColorUtils, GetConfiguration, LocalizeText, RoomWidgetDimmerChangeStateMessage, RoomWidgetDimmerPreviewMessage, RoomWidgetDimmerSavePresetMessage, RoomWidgetUpdateDimmerEvent, RoomWidgetUpdateDimmerStateEvent } from '../../../../../api';
|
import { ColorUtils, GetConfiguration, LocalizeText, RoomWidgetDimmerChangeStateMessage, RoomWidgetDimmerPreviewMessage, RoomWidgetDimmerSavePresetMessage, RoomWidgetUpdateDimmerEvent, RoomWidgetUpdateDimmerStateEvent } from '../../../../../api';
|
||||||
import { Button } from '../../../../../common/Button';
|
import { Base, Button, Column, Flex, Grid, Text } from '../../../../../common';
|
||||||
import { Column } from '../../../../../common/Column';
|
|
||||||
import { Flex } from '../../../../../common/Flex';
|
|
||||||
import { Grid } from '../../../../../common/Grid';
|
|
||||||
import { Text } from '../../../../../common/Text';
|
|
||||||
import { BatchUpdates, CreateEventDispatcherHook } from '../../../../../hooks';
|
import { BatchUpdates, CreateEventDispatcherHook } from '../../../../../hooks';
|
||||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../../../../layout';
|
import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../../../../layout';
|
||||||
import { useRoomContext } from '../../../context/RoomContext';
|
import { useRoomContext } from '../../../context/RoomContext';
|
||||||
@ -31,7 +27,6 @@ export const FurnitureDimmerView: FC<{}> = props =>
|
|||||||
const [ selectedEffectId, setSelectedEffectId ] = useState(0);
|
const [ selectedEffectId, setSelectedEffectId ] = useState(0);
|
||||||
const [ selectedColor, setSelectedColor ] = useState(0);
|
const [ selectedColor, setSelectedColor ] = useState(0);
|
||||||
const [ selectedBrightness, setSelectedBrightness ] = useState(0);
|
const [ selectedBrightness, setSelectedBrightness ] = useState(0);
|
||||||
|
|
||||||
const { eventDispatcher = null, widgetHandler = null } = useRoomContext();
|
const { eventDispatcher = null, widgetHandler = null } = useRoomContext();
|
||||||
|
|
||||||
const onNitroEvent = useCallback((event: NitroEvent) =>
|
const onNitroEvent = useCallback((event: NitroEvent) =>
|
||||||
@ -45,9 +40,12 @@ export const FurnitureDimmerView: FC<{}> = props =>
|
|||||||
|
|
||||||
for(const preset of widgetEvent.presets) presets.push(new DimmerFurnitureWidgetPresetItem(preset.id, preset.type, preset.color, preset.brightness));
|
for(const preset of widgetEvent.presets) presets.push(new DimmerFurnitureWidgetPresetItem(preset.id, preset.type, preset.color, preset.brightness));
|
||||||
|
|
||||||
|
BatchUpdates(() =>
|
||||||
|
{
|
||||||
setPresets(presets);
|
setPresets(presets);
|
||||||
setSelectedPresetId(widgetEvent.selectedPresetId);
|
setSelectedPresetId(widgetEvent.selectedPresetId);
|
||||||
setIsVisible(true);
|
setIsVisible(true);
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case RoomWidgetUpdateDimmerEvent.HIDE: {
|
case RoomWidgetUpdateDimmerEvent.HIDE: {
|
||||||
@ -86,10 +84,13 @@ export const FurnitureDimmerView: FC<{}> = props =>
|
|||||||
|
|
||||||
if(!preset) return;
|
if(!preset) return;
|
||||||
|
|
||||||
|
BatchUpdates(() =>
|
||||||
|
{
|
||||||
setSelectedPresetId(preset.id);
|
setSelectedPresetId(preset.id);
|
||||||
setSelectedEffectId(preset.type);
|
setSelectedEffectId(preset.type);
|
||||||
setSelectedColor(preset.color);
|
setSelectedColor(preset.color);
|
||||||
setSelectedBrightness(preset.light);
|
setSelectedBrightness(preset.light);
|
||||||
|
});
|
||||||
}, [ presets ]);
|
}, [ presets ]);
|
||||||
|
|
||||||
const close = useCallback(() =>
|
const close = useCallback(() =>
|
||||||
@ -133,36 +134,28 @@ export const FurnitureDimmerView: FC<{}> = props =>
|
|||||||
return ~~((((value - MIN_BRIGHTNESS) * (100 - 0)) / (MAX_BRIGHTNESS - MIN_BRIGHTNESS)) + 0);
|
return ~~((((value - MIN_BRIGHTNESS) * (100 - 0)) / (MAX_BRIGHTNESS - MIN_BRIGHTNESS)) + 0);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const isFreeColorMode = useMemo(() =>
|
const isFreeColorMode = useMemo(() => GetConfiguration<boolean>('widget.dimmer.colorwheel', false), []);
|
||||||
{
|
|
||||||
return GetConfiguration<boolean>('widget.dimmer.colorwheel', false);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
if((dimmerState === 0) && (lastDimmerState === 0)) return;
|
if((dimmerState === 0) && (lastDimmerState === 0)) return;
|
||||||
|
|
||||||
console.log('ye')
|
|
||||||
|
|
||||||
widgetHandler.processWidgetMessage(new RoomWidgetDimmerPreviewMessage(selectedColor, selectedBrightness, (selectedEffectId === 2)));
|
widgetHandler.processWidgetMessage(new RoomWidgetDimmerPreviewMessage(selectedColor, selectedBrightness, (selectedEffectId === 2)));
|
||||||
}, [ widgetHandler, dimmerState, lastDimmerState, selectedColor, selectedBrightness, selectedEffectId ]);
|
}, [ widgetHandler, dimmerState, lastDimmerState, selectedColor, selectedBrightness, selectedEffectId ]);
|
||||||
|
|
||||||
if(!isVisible) return null;
|
if(!isVisible) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NitroCardView className="nitro-dimmer">
|
<NitroCardView className="nitro-room-widget-dimmer">
|
||||||
<NitroCardHeaderView headerText={ LocalizeText('widget.dimmer.title') } onCloseClick={ close } />
|
<NitroCardHeaderView headerText={ LocalizeText('widget.dimmer.title') } onCloseClick={ close } />
|
||||||
{ (dimmerState === 1) &&
|
{ (dimmerState === 1) &&
|
||||||
<NitroCardTabsView>
|
<NitroCardTabsView>
|
||||||
{ presets.map(preset =>
|
{ presets.map(preset => <NitroCardTabsItemView key={ preset.id } isActive={ (selectedPresetId === preset.id) } onClick={ event => selectPresetId(preset.id) }>{ LocalizeText(`widget.dimmer.tab.${preset.id}`) }</NitroCardTabsItemView>) }
|
||||||
{
|
|
||||||
return <NitroCardTabsItemView key={ preset.id } isActive={ (selectedPresetId === preset.id) } onClick={ event => selectPresetId(preset.id) }>{ LocalizeText(`widget.dimmer.tab.${preset.id}`) }</NitroCardTabsItemView>
|
|
||||||
}) }
|
|
||||||
</NitroCardTabsView> }
|
</NitroCardTabsView> }
|
||||||
<NitroCardContentView>
|
<NitroCardContentView>
|
||||||
{ (dimmerState === 0) &&
|
{ (dimmerState === 0) &&
|
||||||
<Column alignItems="center">
|
<Column alignItems="center">
|
||||||
<div className="dimmer-banner"></div>
|
<Base className="dimmer-banner" />
|
||||||
<Text center className="bg-muted rounded p-1">{ LocalizeText('widget.dimmer.info.off') }</Text>
|
<Text center className="bg-muted rounded p-1">{ LocalizeText('widget.dimmer.info.off') }</Text>
|
||||||
<Button fullWidth variant="success" onClick={ toggleState }>{ LocalizeText('widget.dimmer.button.on') }</Button>
|
<Button fullWidth variant="success" onClick={ toggleState }>{ LocalizeText('widget.dimmer.button.on') }</Button>
|
||||||
</Column> }
|
</Column> }
|
||||||
@ -173,7 +166,7 @@ export const FurnitureDimmerView: FC<{}> = props =>
|
|||||||
{ isFreeColorMode &&
|
{ isFreeColorMode &&
|
||||||
<input type="color" className="form-control" value={ ColorUtils.makeColorNumberHex(selectedColor) } onChange={ event => setSelectedColor(ColorUtils.convertFromHex(event.target.value)) } /> }
|
<input type="color" className="form-control" value={ ColorUtils.makeColorNumberHex(selectedColor) } onChange={ event => setSelectedColor(ColorUtils.convertFromHex(event.target.value)) } /> }
|
||||||
{ !isFreeColorMode &&
|
{ !isFreeColorMode &&
|
||||||
<Grid columnCount={ 7 }>
|
<Grid gap={ 1 } columnCount={ 7 }>
|
||||||
{ AVAILABLE_COLORS.map((color, index) =>
|
{ AVAILABLE_COLORS.map((color, index) =>
|
||||||
{
|
{
|
||||||
return (
|
return (
|
||||||
@ -193,18 +186,14 @@ export const FurnitureDimmerView: FC<{}> = props =>
|
|||||||
thumbClassName={ 'thumb percent' }
|
thumbClassName={ 'thumb percent' }
|
||||||
renderThumb={ (props, state) => <div {...props}>{ scaledBrightness(state.valueNow) }</div> } />
|
renderThumb={ (props, state) => <div {...props}>{ scaledBrightness(state.valueNow) }</div> } />
|
||||||
</Column>
|
</Column>
|
||||||
<Flex>
|
<Flex alignItems="center" gap={ 1 }>
|
||||||
<input className="form-check-input" type="checkbox" checked={ (selectedEffectId === 2) } onChange={ event => setSelectedEffectId(event.target.checked ? 2 : 1) } />
|
<input className="form-check-input" type="checkbox" checked={ (selectedEffectId === 2) } onChange={ event => setSelectedEffectId(event.target.checked ? 2 : 1) } />
|
||||||
<label className="form-check-label text-black">{ LocalizeText('widget.dimmer.type.checkbox') }</label>
|
<Text>{ LocalizeText('widget.dimmer.type.checkbox') }</Text>
|
||||||
|
</Flex>
|
||||||
|
<Flex gap={ 1 }>
|
||||||
|
<Button fullWidth variant="danger" onClick={ toggleState }>{ LocalizeText('widget.dimmer.button.off') }</Button>
|
||||||
|
<Button fullWidth variant="success" onClick={ applyChanges }>{ LocalizeText('widget.dimmer.button.apply') }</Button>
|
||||||
</Flex>
|
</Flex>
|
||||||
<div className="form-check mb-2">
|
|
||||||
<input className="form-check-input" type="checkbox" checked={ (selectedEffectId === 2) } onChange={ event => setSelectedEffectId(event.target.checked ? 2 : 1) } />
|
|
||||||
<label className="form-check-label text-black">{ LocalizeText('widget.dimmer.type.checkbox') }</label>
|
|
||||||
</div>
|
|
||||||
<div className="d-flex gap-2">
|
|
||||||
<button className="btn btn-danger w-100" onClick={ toggleState }>{ LocalizeText('widget.dimmer.button.off') }</button>
|
|
||||||
<button className="btn btn-success w-100" onClick={ applyChanges }>{ LocalizeText('widget.dimmer.button.apply') }</button>
|
|
||||||
</div>
|
|
||||||
</> }
|
</> }
|
||||||
</NitroCardContentView>
|
</NitroCardContentView>
|
||||||
</NitroCardView>
|
</NitroCardView>
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
.nitro-widget-exchange-credit {
|
|
||||||
width: $nitro-widget-exchange-credit-width;
|
|
||||||
height: $nitro-widget-exchange-credit-height;
|
|
||||||
|
|
||||||
.exchange-image {
|
|
||||||
background-image: url('../../../../../assets/images/room-widgets/exchange-credit/exchange-credit-image.png');
|
|
||||||
width: 103px;
|
|
||||||
height: 103px;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +1,6 @@
|
|||||||
import { FC, useCallback, useState } from 'react';
|
import { FC, useCallback, useState } from 'react';
|
||||||
import { LocalizeText, RoomWidgetCreditFurniRedeemMessage, RoomWidgetUpdateCreditFurniEvent } from '../../../../../api';
|
import { LocalizeText, RoomWidgetCreditFurniRedeemMessage, RoomWidgetUpdateCreditFurniEvent } from '../../../../../api';
|
||||||
import { Base } from '../../../../../common/Base';
|
import { Base, Button, Column, Flex, Text } from '../../../../../common';
|
||||||
import { Button } from '../../../../../common/Button';
|
|
||||||
import { Column } from '../../../../../common/Column';
|
|
||||||
import { Grid } from '../../../../../common/Grid';
|
|
||||||
import { Text } from '../../../../../common/Text';
|
|
||||||
import { BatchUpdates } from '../../../../../hooks';
|
import { BatchUpdates } from '../../../../../hooks';
|
||||||
import { CreateEventDispatcherHook } from '../../../../../hooks/events/event-dispatcher.base';
|
import { CreateEventDispatcherHook } from '../../../../../hooks/events/event-dispatcher.base';
|
||||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout';
|
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout';
|
||||||
@ -17,40 +13,43 @@ export const FurnitureExchangeCreditView: FC<{}> = props =>
|
|||||||
const { eventDispatcher = null, widgetHandler = null } = useRoomContext();
|
const { eventDispatcher = null, widgetHandler = null } = useRoomContext();
|
||||||
|
|
||||||
const onRoomWidgetUpdateCreditFurniEvent = useCallback((event: RoomWidgetUpdateCreditFurniEvent) =>
|
const onRoomWidgetUpdateCreditFurniEvent = useCallback((event: RoomWidgetUpdateCreditFurniEvent) =>
|
||||||
|
{
|
||||||
|
BatchUpdates(() =>
|
||||||
{
|
{
|
||||||
setObjectId(event.objectId);
|
setObjectId(event.objectId);
|
||||||
setValue(event.value);
|
setValue(event.value);
|
||||||
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
CreateEventDispatcherHook(RoomWidgetUpdateCreditFurniEvent.CREDIT_FURNI_UPDATE, eventDispatcher, onRoomWidgetUpdateCreditFurniEvent);
|
CreateEventDispatcherHook(RoomWidgetUpdateCreditFurniEvent.CREDIT_FURNI_UPDATE, eventDispatcher, onRoomWidgetUpdateCreditFurniEvent);
|
||||||
|
|
||||||
const close = useCallback(() =>
|
const close = () =>
|
||||||
{
|
{
|
||||||
BatchUpdates(() =>
|
BatchUpdates(() =>
|
||||||
{
|
{
|
||||||
setObjectId(-1);
|
setObjectId(-1);
|
||||||
setValue(0);
|
setValue(0);
|
||||||
});
|
});
|
||||||
}, []);
|
}
|
||||||
|
|
||||||
const redeem = useCallback(() =>
|
const redeem = () =>
|
||||||
{
|
{
|
||||||
widgetHandler.processWidgetMessage(new RoomWidgetCreditFurniRedeemMessage(RoomWidgetCreditFurniRedeemMessage.REDEEM, objectId));
|
widgetHandler.processWidgetMessage(new RoomWidgetCreditFurniRedeemMessage(RoomWidgetCreditFurniRedeemMessage.REDEEM, objectId));
|
||||||
|
|
||||||
close();
|
close();
|
||||||
}, [ widgetHandler, objectId, close ]);
|
}
|
||||||
|
|
||||||
if(objectId === -1) return null;
|
if(objectId === -1) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NitroCardView className="nitro-widget-exchange-credit" simple={ true }>
|
<NitroCardView className="nitro-widget-exchange-credit" simple>
|
||||||
<NitroCardHeaderView headerText={ LocalizeText('catalog.redeem.dialog.title') } onCloseClick={ close } />
|
<NitroCardHeaderView headerText={ LocalizeText('catalog.redeem.dialog.title') } onCloseClick={ close } />
|
||||||
<NitroCardContentView>
|
<NitroCardContentView center>
|
||||||
<Grid>
|
<Flex overflow="hidden" gap={ 2 }>
|
||||||
<Column center overflow="hidden" size={ 4 }>
|
<Column center>
|
||||||
<Base className="exchange-image" />
|
<Base className="exchange-image" />
|
||||||
</Column>
|
</Column>
|
||||||
<Column justifyContent="between" overflow="hidden" size={ 8 }>
|
<Column grow justifyContent="between" overflow="hidden">
|
||||||
<Column gap={ 1 } overflow="auto">
|
<Column gap={ 1 } overflow="auto">
|
||||||
<Text fontWeight="bold">{ LocalizeText('creditfurni.description', [ 'credits' ], [ value.toString() ]) }</Text>
|
<Text fontWeight="bold">{ LocalizeText('creditfurni.description', [ 'credits' ], [ value.toString() ]) }</Text>
|
||||||
<Text>{ LocalizeText('creditfurni.prompt') }</Text>
|
<Text>{ LocalizeText('creditfurni.prompt') }</Text>
|
||||||
@ -59,7 +58,7 @@ export const FurnitureExchangeCreditView: FC<{}> = props =>
|
|||||||
{ LocalizeText('catalog.redeem.dialog.button.exchange') }
|
{ LocalizeText('catalog.redeem.dialog.button.exchange') }
|
||||||
</Button>
|
</Button>
|
||||||
</Column>
|
</Column>
|
||||||
</Grid>
|
</Flex>
|
||||||
</NitroCardContentView>
|
</NitroCardContentView>
|
||||||
</NitroCardView>
|
</NitroCardView>
|
||||||
);
|
);
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
.nitro-external-image-widget {
|
|
||||||
|
|
||||||
.picture-preview {
|
|
||||||
width: 320px;
|
|
||||||
height: 320px;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,7 @@
|
|||||||
import { FC, useCallback, useState } from 'react';
|
import { FC, useCallback, useState } from 'react';
|
||||||
import { IPhotoData, LocalizeText, RoomWidgetUpdateExternalImageEvent } from '../../../../../api';
|
import { IPhotoData, LocalizeText, RoomWidgetUpdateExternalImageEvent } from '../../../../../api';
|
||||||
import { CreateEventDispatcherHook } from '../../../../../hooks';
|
import { Flex, Text } from '../../../../../common';
|
||||||
|
import { BatchUpdates, CreateEventDispatcherHook } from '../../../../../hooks';
|
||||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout';
|
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout';
|
||||||
import { useRoomContext } from '../../../context/RoomContext';
|
import { useRoomContext } from '../../../context/RoomContext';
|
||||||
|
|
||||||
@ -10,19 +11,23 @@ export const FurnitureExternalImageView: FC<{}> = props =>
|
|||||||
const [ photoData, setPhotoData ] = useState<IPhotoData>(null);
|
const [ photoData, setPhotoData ] = useState<IPhotoData>(null);
|
||||||
const { eventDispatcher = null } = useRoomContext();
|
const { eventDispatcher = null } = useRoomContext();
|
||||||
|
|
||||||
const close = useCallback(() =>
|
const close = () =>
|
||||||
{
|
{
|
||||||
setObjectId(-1);
|
setObjectId(-1);
|
||||||
setPhotoData(null)
|
setPhotoData(null)
|
||||||
}, []);
|
}
|
||||||
|
|
||||||
const onRoomWidgetUpdateExternalImageEvent = useCallback((event: RoomWidgetUpdateExternalImageEvent) =>
|
const onRoomWidgetUpdateExternalImageEvent = useCallback((event: RoomWidgetUpdateExternalImageEvent) =>
|
||||||
{
|
{
|
||||||
switch(event.type)
|
switch(event.type)
|
||||||
{
|
{
|
||||||
case RoomWidgetUpdateExternalImageEvent.UPDATE_EXTERNAL_IMAGE: {
|
case RoomWidgetUpdateExternalImageEvent.UPDATE_EXTERNAL_IMAGE: {
|
||||||
|
|
||||||
|
BatchUpdates(() =>
|
||||||
|
{
|
||||||
setObjectId(event.objectId);
|
setObjectId(event.objectId);
|
||||||
setPhotoData(event.photoData);
|
setPhotoData(event.photoData);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
@ -35,17 +40,16 @@ export const FurnitureExternalImageView: FC<{}> = props =>
|
|||||||
<NitroCardView className="nitro-external-image-widget">
|
<NitroCardView className="nitro-external-image-widget">
|
||||||
<NitroCardHeaderView headerText={ '' } onCloseClick={ close } />
|
<NitroCardHeaderView headerText={ '' } onCloseClick={ close } />
|
||||||
<NitroCardContentView>
|
<NitroCardContentView>
|
||||||
<div className="d-flex justify-content-center align-items-center picture-preview border mb-2" style={ photoData.w ? { backgroundImage: 'url(' + photoData.w + ')' } : {} }>
|
<Flex center className="picture-preview border border-black" style={ photoData.w ? { backgroundImage: 'url(' + photoData.w + ')' } : {} }>
|
||||||
{ !photoData.w &&
|
{ !photoData.w &&
|
||||||
<div className="text-black fw-bold">
|
<Text bold>{ LocalizeText('camera.loading') }</Text> }
|
||||||
{ LocalizeText('camera.loading') }
|
</Flex>
|
||||||
</div> }
|
{ photoData.m && photoData.m.length &&
|
||||||
</div>
|
<Text center>{ photoData.m }</Text> }
|
||||||
<span className="text-center text-black">{ photoData.m && <div>{ photoData.m }</div> }</span>
|
<Flex alignItems="center" justifyContent="between">
|
||||||
<div className="d-flex align-items-center justify-content-between">
|
<Text>{ (photoData.n || '') }</Text>
|
||||||
<span className="text-black">{ (photoData.n || '') }</span>
|
<Text>{ new Date(photoData.t * 1000).toLocaleDateString() }</Text>
|
||||||
<span className="text-black">{ new Date(photoData.t * 1000).toLocaleDateString() }</span>
|
</Flex>
|
||||||
</div>
|
|
||||||
</NitroCardContentView>
|
</NitroCardContentView>
|
||||||
</NitroCardView>
|
</NitroCardView>
|
||||||
);
|
);
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user