mirror of
https://github.com/billsonnn/nitro-react.git
synced 2024-11-26 23:50:52 +01:00
Merge branch 'feature/marketplace' into more-layout-changes
This commit is contained in:
commit
96c048878c
@ -127,6 +127,7 @@ export const App: FC<{}> = props =>
|
|||||||
return (
|
return (
|
||||||
<div className="nitro-app overflow-hidden">
|
<div className="nitro-app overflow-hidden">
|
||||||
<div id="nitro-alerts-container" />
|
<div id="nitro-alerts-container" />
|
||||||
|
<div id="nitro-confirms-container" />
|
||||||
{ (!isReady || isError) && <LoadingView isError={ isError } message={ message } /> }
|
{ (!isReady || isError) && <LoadingView isError={ isError } message={ message } /> }
|
||||||
<TransitionAnimation type={ TransitionAnimationTypes.FADE_IN } inProp={ (isReady && !isError) }>
|
<TransitionAnimation type={ TransitionAnimationTypes.FADE_IN } inProp={ (isReady && !isError) }>
|
||||||
<MainView />
|
<MainView />
|
||||||
|
@ -136,24 +136,24 @@ export class RoomWidgetAvatarInfoHandler extends RoomWidgetHandler
|
|||||||
{
|
{
|
||||||
if(userData.ownerId === ownerId)
|
if(userData.ownerId === ownerId)
|
||||||
{
|
{
|
||||||
if(userData.hasSaddle && (specialType === FurniCategory._Str_6096)) replace = true;
|
if(userData.hasSaddle && (specialType === FurniCategory.PET_SADDLE)) replace = true;
|
||||||
|
|
||||||
const figureParts = userData.figure.split(' ');
|
const figureParts = userData.figure.split(' ');
|
||||||
const figurePart = (figureParts.length ? parseInt(figureParts[0]) : -1);
|
const figurePart = (figureParts.length ? parseInt(figureParts[0]) : -1);
|
||||||
|
|
||||||
if(figurePart === part)
|
if(figurePart === part)
|
||||||
{
|
{
|
||||||
if(specialType === FurniCategory._Str_6915)
|
if(specialType === FurniCategory.MONSTERPLANT_REVIVAL)
|
||||||
{
|
{
|
||||||
if(!userData.canRevive) continue;
|
if(!userData.canRevive) continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(specialType === FurniCategory._Str_8726)
|
if(specialType === FurniCategory.MONSTERPLANT_REBREED)
|
||||||
{
|
{
|
||||||
if((userData.petLevel < 7) || userData.canRevive || userData.canBreed) continue;
|
if((userData.petLevel < 7) || userData.canRevive || userData.canBreed) continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(specialType === FurniCategory._Str_9449)
|
if(specialType === FurniCategory.MONSTERPLANT_FERTILIZE)
|
||||||
{
|
{
|
||||||
if((userData.petLevel >= 7) || userData.canRevive) continue;
|
if((userData.petLevel >= 7) || userData.canRevive) continue;
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import { AvatarExpressionEnum, HabboClubLevelEnum, NitroEvent, RoomControllerLevel, RoomSessionChatEvent, RoomSettingsComposer, RoomWidgetEnum, RoomZoomEvent, TextureUtils } from '@nitrots/nitro-renderer';
|
import { AvatarExpressionEnum, HabboClubLevelEnum, NitroEvent, RoomControllerLevel, RoomSessionChatEvent, RoomSettingsComposer, RoomWidgetEnum, RoomZoomEvent, TextureUtils } from '@nitrots/nitro-renderer';
|
||||||
import { GetConfiguration, GetNitroInstance } from '../../..';
|
import { GetConfiguration, GetNitroInstance } from '../../..';
|
||||||
import { GetRoomEngine, GetSessionDataManager } from '../../../..';
|
import { GetRoomEngine, GetSessionDataManager, LocalizeText } from '../../../..';
|
||||||
import { FloorplanEditorEvent } from '../../../../../events/floorplan-editor/FloorplanEditorEvent';
|
import { FloorplanEditorEvent } from '../../../../../events/floorplan-editor/FloorplanEditorEvent';
|
||||||
import { dispatchUiEvent } from '../../../../../hooks';
|
import { dispatchUiEvent } from '../../../../../hooks';
|
||||||
import { SendMessageHook } from '../../../../../hooks/messages';
|
import { SendMessageHook } from '../../../../../hooks/messages';
|
||||||
|
import { NotificationUtilities } from '../../../../../views/notification-center/common/NotificationUtilities';
|
||||||
import { RoomWidgetFloodControlEvent, RoomWidgetUpdateEvent } from '../events';
|
import { RoomWidgetFloodControlEvent, RoomWidgetUpdateEvent } from '../events';
|
||||||
import { RoomWidgetChatMessage, RoomWidgetChatSelectAvatarMessage, RoomWidgetChatTypingMessage, RoomWidgetMessage, RoomWidgetRequestWidgetMessage } from '../messages';
|
import { RoomWidgetChatMessage, RoomWidgetChatSelectAvatarMessage, RoomWidgetChatTypingMessage, RoomWidgetMessage, RoomWidgetRequestWidgetMessage } from '../messages';
|
||||||
import { RoomWidgetHandler } from './RoomWidgetHandler';
|
import { RoomWidgetHandler } from './RoomWidgetHandler';
|
||||||
@ -127,10 +128,11 @@ export class RoomWidgetChatInputHandler extends RoomWidgetHandler
|
|||||||
newWindow.document.write(image.outerHTML);
|
newWindow.document.write(image.outerHTML);
|
||||||
return null;
|
return null;
|
||||||
case ':pickall':
|
case ':pickall':
|
||||||
// this.container.notificationService.alertWithConfirm('${room.confirm.pick_all}', '${generic.alert.title}', () =>
|
NotificationUtilities.confirm(LocalizeText('room.confirm.pick_all'), () =>
|
||||||
// {
|
{
|
||||||
// GetSessionDataManager().sendSpecialCommandMessage(':pickall');
|
GetSessionDataManager().sendSpecialCommandMessage(':pickall');
|
||||||
// });
|
},
|
||||||
|
null, null, null, LocalizeText('generic.alert.title'));
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
case ':furni':
|
case ':furni':
|
||||||
|
@ -1,26 +1,26 @@
|
|||||||
export class FurniCategory
|
export class FurniCategory
|
||||||
{
|
{
|
||||||
public static DEFAULT: number = 1;
|
public static DEFAULT: number = 1;
|
||||||
public static _Str_3639: number = 2;
|
public static WALL_PAPER: number = 2;
|
||||||
public static _Str_3683: number = 3;
|
public static FLOOR: number = 3;
|
||||||
public static _Str_3432: number = 4;
|
public static LANDSCAPE: number = 4;
|
||||||
public static _Str_12351: number = 5;
|
public static POST_IT: number = 5;
|
||||||
public static _Str_5186: number = 6;
|
public static POSTER: number = 6;
|
||||||
public static _Str_21911: number = 7;
|
public static SOUND_SET: number = 7;
|
||||||
public static _Str_9125: number = 8;
|
public static TRAX_SONG: number = 8;
|
||||||
public static _Str_5922: number = 9;
|
public static PRESENT: number = 9;
|
||||||
public static _Str_18231: number = 10;
|
public static ECOTRON_BOX: number = 10;
|
||||||
public static _Str_4255: number = 11;
|
public static TROPHY: number = 11;
|
||||||
public static _Str_19933: number = 12;
|
public static CREDIT_FURNI: number = 12;
|
||||||
public static _Str_7696: number = 13;
|
public static PET_SHAMPOO: number = 13;
|
||||||
public static _Str_7297: number = 14;
|
public static PET_CUSTOM_PART: number = 14;
|
||||||
public static _Str_7954: number = 15;
|
public static PET_CUSTOM_PART_SHAMPOO: number = 15;
|
||||||
public static _Str_6096: number = 16;
|
public static PET_SADDLE: number = 16;
|
||||||
public static _Str_12454: number = 17;
|
public static GUILD_FURNI: number = 17;
|
||||||
public static _Str_19144: number = 18;
|
public static GAME_FURNI: number = 18;
|
||||||
public static MONSTERPLANT_SEED: number = 19;
|
public static MONSTERPLANT_SEED: number = 19;
|
||||||
public static _Str_6915: number = 20;
|
public static MONSTERPLANT_REVIVAL: number = 20;
|
||||||
public static _Str_8726: number = 21;
|
public static MONSTERPLANT_REBREED: number = 21;
|
||||||
public static _Str_9449: number = 22;
|
public static MONSTERPLANT_FERTILIZE: number = 22;
|
||||||
public static _Str_12534: number = 23;
|
public static FIGURE_PURCHASABLE_SET: number = 23;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { FurnitureListItemParser, FurniturePlacePaintComposer, IObjectData, RoomObjectCategory, RoomObjectPlacementSource } from '@nitrots/nitro-renderer';
|
import { FurnitureListItemParser, FurniturePlacePaintComposer, IObjectData, RoomObjectCategory, RoomObjectPlacementSource } from '@nitrots/nitro-renderer';
|
||||||
import { GetRoomEngine } from '../../../api';
|
import { GetRoomEngine } from '../../../api';
|
||||||
import { InventoryEvent } from '../../../events';
|
import { InventoryEvent } from '../../../events';
|
||||||
|
import { CatalogPostMarketplaceOfferEvent } from '../../../events/catalog/CatalogPostMarketplaceOfferEvent';
|
||||||
import { dispatchUiEvent } from '../../../hooks/events/ui/ui-event';
|
import { dispatchUiEvent } from '../../../hooks/events/ui/ui-event';
|
||||||
import { SendMessageHook } from '../../../hooks/messages/message-event';
|
import { SendMessageHook } from '../../../hooks/messages/message-event';
|
||||||
import { FurniCategory } from './FurniCategory';
|
import { FurniCategory } from './FurniCategory';
|
||||||
@ -18,7 +19,7 @@ export function attemptItemPlacement(groupItem: GroupItem, flag: boolean = false
|
|||||||
|
|
||||||
if(!item) return false;
|
if(!item) return false;
|
||||||
|
|
||||||
if((item.category === FurniCategory._Str_3683) || (item.category === FurniCategory._Str_3639) || (item.category === FurniCategory._Str_3432))
|
if((item.category === FurniCategory.FLOOR) || (item.category === FurniCategory.WALL_PAPER) || (item.category === FurniCategory.LANDSCAPE))
|
||||||
{
|
{
|
||||||
if(flag) return false;
|
if(flag) return false;
|
||||||
|
|
||||||
@ -36,7 +37,7 @@ export function attemptItemPlacement(groupItem: GroupItem, flag: boolean = false
|
|||||||
if(item.isWallItem) category = RoomObjectCategory.WALL;
|
if(item.isWallItem) category = RoomObjectCategory.WALL;
|
||||||
else category = RoomObjectCategory.FLOOR;
|
else category = RoomObjectCategory.FLOOR;
|
||||||
|
|
||||||
if((item.category === FurniCategory._Str_5186)) // or external image from furnidata
|
if((item.category === FurniCategory.POSTER)) // or external image from furnidata
|
||||||
{
|
{
|
||||||
isMoving = GetRoomEngine().processRoomObjectPlacement(RoomObjectPlacementSource.INVENTORY, item.id, category, item.type, item.stuffData.getLegacyString());
|
isMoving = GetRoomEngine().processRoomObjectPlacement(RoomObjectPlacementSource.INVENTORY, item.id, category, item.type, item.stuffData.getLegacyString());
|
||||||
}
|
}
|
||||||
@ -55,6 +56,17 @@ export function attemptItemPlacement(groupItem: GroupItem, flag: boolean = false
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function attemptPlaceMarketplaceOffer(groupItem: GroupItem): boolean
|
||||||
|
{
|
||||||
|
const item = groupItem.getLastItem();
|
||||||
|
|
||||||
|
if(!item) return false;
|
||||||
|
|
||||||
|
if(!item.sellable) return false;
|
||||||
|
|
||||||
|
dispatchUiEvent(new CatalogPostMarketplaceOfferEvent(item));
|
||||||
|
}
|
||||||
|
|
||||||
function cancelRoomObjectPlacement(): void
|
function cancelRoomObjectPlacement(): void
|
||||||
{
|
{
|
||||||
if(getPlacingItemId() === -1) return;
|
if(getPlacingItemId() === -1) return;
|
||||||
@ -108,7 +120,7 @@ function getAllItemIds(groupItems: GroupItem[]): number[]
|
|||||||
{
|
{
|
||||||
let totalCount = groupItem.getTotalCount();
|
let totalCount = groupItem.getTotalCount();
|
||||||
|
|
||||||
if(groupItem.category === FurniCategory._Str_12351) totalCount = 1;
|
if(groupItem.category === FurniCategory.POST_IT) totalCount = 1;
|
||||||
|
|
||||||
let i = 0;
|
let i = 0;
|
||||||
|
|
||||||
@ -240,7 +252,7 @@ function addGroupableFurnitureItem(set: GroupItem[], item: FurnitureItem, unseen
|
|||||||
{
|
{
|
||||||
if((groupItem.type === item.type) && (groupItem.isWallItem === item.isWallItem) && groupItem.isGroupable)
|
if((groupItem.type === item.type) && (groupItem.isWallItem === item.isWallItem) && groupItem.isGroupable)
|
||||||
{
|
{
|
||||||
if(item.category === FurniCategory._Str_5186)
|
if(item.category === FurniCategory.POSTER)
|
||||||
{
|
{
|
||||||
if(groupItem.stuffData.getLegacyString() === item.stuffData.getLegacyString())
|
if(groupItem.stuffData.getLegacyString() === item.stuffData.getLegacyString())
|
||||||
{
|
{
|
||||||
@ -250,7 +262,7 @@ function addGroupableFurnitureItem(set: GroupItem[], item: FurnitureItem, unseen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(item.category === FurniCategory._Str_12454)
|
else if(item.category === FurniCategory.GUILD_FURNI)
|
||||||
{
|
{
|
||||||
if(item.stuffData.compare(groupItem.stuffData))
|
if(item.stuffData.compare(groupItem.stuffData))
|
||||||
{
|
{
|
||||||
@ -309,7 +321,7 @@ export function createGroupItem(type: number, category: number, stuffData: IObje
|
|||||||
{
|
{
|
||||||
// const iconImage: HTMLImageElement = null;
|
// const iconImage: HTMLImageElement = null;
|
||||||
|
|
||||||
if(category === FurniCategory._Str_3639)
|
if(category === FurniCategory.WALL_PAPER)
|
||||||
{
|
{
|
||||||
// const icon = this._windowManager.assets.getAssetByName("inventory_furni_icon_wallpaper");
|
// const icon = this._windowManager.assets.getAssetByName("inventory_furni_icon_wallpaper");
|
||||||
// if (icon != null)
|
// if (icon != null)
|
||||||
@ -318,7 +330,7 @@ export function createGroupItem(type: number, category: number, stuffData: IObje
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(category === FurniCategory._Str_3683)
|
else if(category === FurniCategory.FLOOR)
|
||||||
{
|
{
|
||||||
// const icon = this._windowManager.assets.getAssetByName("inventory_furni_icon_floor");
|
// const icon = this._windowManager.assets.getAssetByName("inventory_furni_icon_floor");
|
||||||
// if (icon != null)
|
// if (icon != null)
|
||||||
@ -327,7 +339,7 @@ export function createGroupItem(type: number, category: number, stuffData: IObje
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(category === FurniCategory._Str_3432)
|
else if(category === FurniCategory.LANDSCAPE)
|
||||||
{
|
{
|
||||||
// const icon = this._windowManager.assets.getAssetByName("inventory_furni_icon_landscape");
|
// const icon = this._windowManager.assets.getAssetByName("inventory_furni_icon_landscape");
|
||||||
// if (icon != null)
|
// if (icon != null)
|
||||||
|
@ -199,7 +199,7 @@ export class GroupItem
|
|||||||
|
|
||||||
public getTotalCount(): number
|
public getTotalCount(): number
|
||||||
{
|
{
|
||||||
if(this._category === FurniCategory._Str_12351)
|
if(this._category === FurniCategory.POST_IT)
|
||||||
{
|
{
|
||||||
let count = 0;
|
let count = 0;
|
||||||
let index = 0;
|
let index = 0;
|
||||||
@ -221,7 +221,7 @@ export class GroupItem
|
|||||||
|
|
||||||
public getUnlockedCount(): number
|
public getUnlockedCount(): number
|
||||||
{
|
{
|
||||||
if(this.category === FurniCategory._Str_12351) return this.getTotalCount();
|
if(this.category === FurniCategory.POST_IT) return this.getTotalCount();
|
||||||
|
|
||||||
let count = 0;
|
let count = 0;
|
||||||
let index = 0;
|
let index = 0;
|
||||||
@ -318,10 +318,10 @@ export class GroupItem
|
|||||||
|
|
||||||
switch(this._category)
|
switch(this._category)
|
||||||
{
|
{
|
||||||
case FurniCategory._Str_5186:
|
case FurniCategory.POSTER:
|
||||||
key = (('poster_' + k.stuffData.getLegacyString()) + '_name');
|
key = (('poster_' + k.stuffData.getLegacyString()) + '_name');
|
||||||
break;
|
break;
|
||||||
case FurniCategory._Str_9125:
|
case FurniCategory.TRAX_SONG:
|
||||||
this._name = 'SONG_NAME';
|
this._name = 'SONG_NAME';
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
@ -442,6 +442,13 @@ export class GroupItem
|
|||||||
return (item ? item.isGroupable : false);
|
return (item ? item.isGroupable : false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public get isSellable(): boolean
|
||||||
|
{
|
||||||
|
const item = this.getItemByIndex(0);
|
||||||
|
|
||||||
|
return (item ? item.sellable : false);
|
||||||
|
}
|
||||||
|
|
||||||
public get items(): FurnitureItem[]
|
public get items(): FurnitureItem[]
|
||||||
{
|
{
|
||||||
return this._items;
|
return this._items;
|
||||||
|
@ -30,12 +30,12 @@ export function parseTradeItems(items: ItemDataStructure[], _arg_2: AdvancedMap<
|
|||||||
name = ('itemid' + item.itemId);
|
name = ('itemid' + item.itemId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(item.category === FurniCategory._Str_5186)
|
if(item.category === FurniCategory.POSTER)
|
||||||
{
|
{
|
||||||
name = (item.itemId + 'poster' + item.stuffData.getLegacyString());
|
name = (item.itemId + 'poster' + item.stuffData.getLegacyString());
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(item.category === FurniCategory._Str_12454)
|
else if(item.category === FurniCategory.GUILD_FURNI)
|
||||||
{
|
{
|
||||||
name = '';
|
name = '';
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import { LimitedEditionCompactPlateView } from '../../../../views/shared/limited
|
|||||||
import { RarityLevelView } from '../../../../views/shared/rarity-level/RarityLevelView';
|
import { RarityLevelView } from '../../../../views/shared/rarity-level/RarityLevelView';
|
||||||
import { RoomPreviewerView } from '../../../../views/shared/room-previewer/RoomPreviewerView';
|
import { RoomPreviewerView } from '../../../../views/shared/room-previewer/RoomPreviewerView';
|
||||||
import { FurniCategory } from '../../common/FurniCategory';
|
import { FurniCategory } from '../../common/FurniCategory';
|
||||||
import { attemptItemPlacement } from '../../common/FurnitureUtilities';
|
import { attemptItemPlacement, attemptPlaceMarketplaceOffer } from '../../common/FurnitureUtilities';
|
||||||
import { GroupItem } from '../../common/GroupItem';
|
import { GroupItem } from '../../common/GroupItem';
|
||||||
import { useInventoryContext } from '../../context/InventoryContext';
|
import { useInventoryContext } from '../../context/InventoryContext';
|
||||||
import { InventoryFurnitureActions } from '../../reducers/InventoryFurnitureReducer';
|
import { InventoryFurnitureActions } from '../../reducers/InventoryFurnitureReducer';
|
||||||
@ -80,15 +80,15 @@ export const InventoryFurnitureView: FC<InventoryFurnitureViewProps> = props =>
|
|||||||
roomPreviewer.updateObjectRoom(floorType, wallType, landscapeType);
|
roomPreviewer.updateObjectRoom(floorType, wallType, landscapeType);
|
||||||
roomPreviewer.updateRoomWallsAndFloorVisibility(true, true);
|
roomPreviewer.updateRoomWallsAndFloorVisibility(true, true);
|
||||||
|
|
||||||
if((furnitureItem.category === FurniCategory._Str_3639) || (furnitureItem.category === FurniCategory._Str_3683) || (furnitureItem.category === FurniCategory._Str_3432))
|
if((furnitureItem.category === FurniCategory.WALL_PAPER) || (furnitureItem.category === FurniCategory.FLOOR) || (furnitureItem.category === FurniCategory.LANDSCAPE))
|
||||||
{
|
{
|
||||||
floorType = ((furnitureItem.category === FurniCategory._Str_3683) ? groupItem.stuffData.getLegacyString() : floorType);
|
floorType = ((furnitureItem.category === FurniCategory.FLOOR) ? groupItem.stuffData.getLegacyString() : floorType);
|
||||||
wallType = ((furnitureItem.category === FurniCategory._Str_3639) ? groupItem.stuffData.getLegacyString() : wallType);
|
wallType = ((furnitureItem.category === FurniCategory.WALL_PAPER) ? groupItem.stuffData.getLegacyString() : wallType);
|
||||||
landscapeType = ((furnitureItem.category === FurniCategory._Str_3432) ? groupItem.stuffData.getLegacyString() : landscapeType);
|
landscapeType = ((furnitureItem.category === FurniCategory.LANDSCAPE) ? groupItem.stuffData.getLegacyString() : landscapeType);
|
||||||
|
|
||||||
roomPreviewer.updateObjectRoom(floorType, wallType, landscapeType);
|
roomPreviewer.updateObjectRoom(floorType, wallType, landscapeType);
|
||||||
|
|
||||||
if(furnitureItem.category === FurniCategory._Str_3432)
|
if(furnitureItem.category === FurniCategory.LANDSCAPE)
|
||||||
{
|
{
|
||||||
const data = GetSessionDataManager().getWallItemDataByName('noob_window_double');
|
const data = GetSessionDataManager().getWallItemDataByName('noob_window_double');
|
||||||
|
|
||||||
@ -133,6 +133,11 @@ export const InventoryFurnitureView: FC<InventoryFurnitureViewProps> = props =>
|
|||||||
<Button variant="success" size="sm" onClick={ event => attemptItemPlacement(groupItem) }>
|
<Button variant="success" size="sm" onClick={ event => attemptItemPlacement(groupItem) }>
|
||||||
{ LocalizeText('inventory.furni.placetoroom') }
|
{ LocalizeText('inventory.furni.placetoroom') }
|
||||||
</Button> }
|
</Button> }
|
||||||
|
{ (groupItem && groupItem.isSellable) &&
|
||||||
|
<Button variant="primary" size="sm" onClick={ event => attemptPlaceMarketplaceOffer(groupItem) }>
|
||||||
|
{ LocalizeText('inventory.marketplace.sell') }
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
</Column> }
|
</Column> }
|
||||||
</Column>
|
</Column>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
@ -10,6 +10,7 @@ import { Grid } from '../../../../common/Grid';
|
|||||||
import { LayoutGridItem } from '../../../../common/layout/LayoutGridItem';
|
import { LayoutGridItem } from '../../../../common/layout/LayoutGridItem';
|
||||||
import { Text } from '../../../../common/Text';
|
import { Text } from '../../../../common/Text';
|
||||||
import { SendMessageHook } from '../../../../hooks/messages';
|
import { SendMessageHook } from '../../../../hooks/messages';
|
||||||
|
import { NotificationAlertType } from '../../../../views/notification-center/common/NotificationAlertType';
|
||||||
import { NotificationUtilities } from '../../../../views/notification-center/common/NotificationUtilities';
|
import { NotificationUtilities } from '../../../../views/notification-center/common/NotificationUtilities';
|
||||||
import { FurniCategory } from '../../common/FurniCategory';
|
import { FurniCategory } from '../../common/FurniCategory';
|
||||||
import { GroupItem } from '../../common/GroupItem';
|
import { GroupItem } from '../../common/GroupItem';
|
||||||
@ -49,13 +50,13 @@ export const InventoryTradeView: FC<InventoryTradeViewProps> = props =>
|
|||||||
|
|
||||||
let type = spriteId.toString();
|
let type = spriteId.toString();
|
||||||
|
|
||||||
if(category === FurniCategory._Str_5186)
|
if(category === FurniCategory.POSTER)
|
||||||
{
|
{
|
||||||
type = ((type + 'poster') + stuffData.getLegacyString());
|
type = ((type + 'poster') + stuffData.getLegacyString());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(category === FurniCategory._Str_12454)
|
if(category === FurniCategory.GUILD_FURNI)
|
||||||
{
|
{
|
||||||
type = _Str_16998(spriteId, stuffData);
|
type = _Str_16998(spriteId, stuffData);
|
||||||
}
|
}
|
||||||
@ -121,7 +122,7 @@ export const InventoryTradeView: FC<InventoryTradeViewProps> = props =>
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//this._notificationService.alert('${trading.items.too_many_items.desc}', '${trading.items.too_many_items.title}');
|
NotificationUtilities.simpleAlert(LocalizeText('trading.items.too_many_items.desc'), NotificationAlertType.DEFAULT, null, null, LocalizeText('trading.items.too_many_items.title'));
|
||||||
}
|
}
|
||||||
}, [ groupItem, tradeData, canTradeItem ]);
|
}, [ groupItem, tradeData, canTradeItem ]);
|
||||||
|
|
||||||
@ -157,6 +158,7 @@ export const InventoryTradeView: FC<InventoryTradeViewProps> = props =>
|
|||||||
case TradeState.TRADING_STATE_RUNNING:
|
case TradeState.TRADING_STATE_RUNNING:
|
||||||
if(!tradeData.otherUser.itemCount && !tradeData.ownUser.accepts)
|
if(!tradeData.otherUser.itemCount && !tradeData.ownUser.accepts)
|
||||||
{
|
{
|
||||||
|
// eslint-disable-next-line no-template-curly-in-string
|
||||||
NotificationUtilities.simpleAlert(LocalizeText('${inventory.trading.warning.other_not_offering}'), null, null, null);
|
NotificationUtilities.simpleAlert(LocalizeText('${inventory.trading.warning.other_not_offering}'), null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
20
src/events/catalog/CatalogPostMarketplaceOfferEvent.ts
Normal file
20
src/events/catalog/CatalogPostMarketplaceOfferEvent.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { CatalogEvent } from '.';
|
||||||
|
import { FurnitureItem } from '../../components/inventory/common/FurnitureItem';
|
||||||
|
|
||||||
|
export class CatalogPostMarketplaceOfferEvent extends CatalogEvent
|
||||||
|
{
|
||||||
|
public static readonly POST_MARKETPLACE = 'CE_POST_MARKETPLACE';
|
||||||
|
|
||||||
|
private _item: FurnitureItem;
|
||||||
|
|
||||||
|
constructor(item: FurnitureItem)
|
||||||
|
{
|
||||||
|
super(CatalogPostMarketplaceOfferEvent.POST_MARKETPLACE);
|
||||||
|
this._item = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get item(): FurnitureItem
|
||||||
|
{
|
||||||
|
return this._item;
|
||||||
|
}
|
||||||
|
}
|
62
src/events/notification-center/NotificationConfirmEvent.ts
Normal file
62
src/events/notification-center/NotificationConfirmEvent.ts
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import { NitroEvent } from '@nitrots/nitro-renderer';
|
||||||
|
|
||||||
|
export class NotificationConfirmEvent extends NitroEvent
|
||||||
|
{
|
||||||
|
public static CONFIRM: string = 'NCE_CONFIRM';
|
||||||
|
|
||||||
|
private _confirmType: string;
|
||||||
|
private _message: string;
|
||||||
|
private _onConfirm: Function;
|
||||||
|
private _onCancel: Function;
|
||||||
|
private _confirmText: string;
|
||||||
|
private _cancelText: string;
|
||||||
|
private _title: string;
|
||||||
|
|
||||||
|
constructor(confirmType: string, message: string, onConfirm: Function, onCancel: Function, confirmText: string, cancelText: string, title: string)
|
||||||
|
{
|
||||||
|
super(NotificationConfirmEvent.CONFIRM);
|
||||||
|
|
||||||
|
this._confirmType = confirmType;
|
||||||
|
this._message = message;
|
||||||
|
this._onConfirm = onConfirm;
|
||||||
|
this._onCancel = onCancel;
|
||||||
|
this._confirmText = confirmText;
|
||||||
|
this._cancelText = cancelText;
|
||||||
|
this._title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get confirmType(): string
|
||||||
|
{
|
||||||
|
return this._confirmType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get message(): string
|
||||||
|
{
|
||||||
|
return this._message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get onConfirm(): Function
|
||||||
|
{
|
||||||
|
return this._onConfirm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get onCancel(): Function
|
||||||
|
{
|
||||||
|
return this._onCancel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get confirmText(): string
|
||||||
|
{
|
||||||
|
return this._confirmText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get cancelText(): string
|
||||||
|
{
|
||||||
|
return this._cancelText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get title(): string
|
||||||
|
{
|
||||||
|
return this._title;
|
||||||
|
}
|
||||||
|
}
|
@ -2,3 +2,4 @@ export * from './NotificationAlertEvent';
|
|||||||
export * from './NotificationBubbleEvent';
|
export * from './NotificationBubbleEvent';
|
||||||
export * from './NotificationCenterAlertEvent';
|
export * from './NotificationCenterAlertEvent';
|
||||||
export * from './NotificationCenterEvent';
|
export * from './NotificationCenterEvent';
|
||||||
|
export * from './NotificationConfirmEvent';
|
||||||
|
@ -16,6 +16,7 @@ import { CatalogReducer, initialCatalog } from './reducers/CatalogReducer';
|
|||||||
import { CatalogGiftView } from './views/gift/CatalogGiftView';
|
import { CatalogGiftView } from './views/gift/CatalogGiftView';
|
||||||
import { ACTIVE_PAGES, CatalogNavigationView } from './views/navigation/CatalogNavigationView';
|
import { ACTIVE_PAGES, CatalogNavigationView } from './views/navigation/CatalogNavigationView';
|
||||||
import { CatalogPageView } from './views/page/CatalogPageView';
|
import { CatalogPageView } from './views/page/CatalogPageView';
|
||||||
|
import { MarketplacePostOfferView } from './views/page/layout/marketplace/post-offer/MarketplacePostOfferView';
|
||||||
|
|
||||||
export const CatalogView: FC<CatalogViewProps> = props =>
|
export const CatalogView: FC<CatalogViewProps> = props =>
|
||||||
{
|
{
|
||||||
@ -224,6 +225,7 @@ export const CatalogView: FC<CatalogViewProps> = props =>
|
|||||||
</NitroCardContentView>
|
</NitroCardContentView>
|
||||||
</NitroCardView> }
|
</NitroCardView> }
|
||||||
<CatalogGiftView />
|
<CatalogGiftView />
|
||||||
|
<MarketplacePostOfferView />
|
||||||
</CatalogContextProvider>
|
</CatalogContextProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
@import './frontpage4/CatalogLayoutFrontpage4View';
|
@import './frontpage4/CatalogLayoutFrontpage4View';
|
||||||
@import './info-loyalty/CatalogLayoutInfoLoyaltyView.scss';
|
@import './info-loyalty/CatalogLayoutInfoLoyaltyView.scss';
|
||||||
@import './vip-buy/CatalogLayoutVipBuyView';
|
@import './vip-buy/CatalogLayoutVipBuyView';
|
||||||
|
@import './marketplace/marketplace-item/MarketplaceItemView';
|
||||||
|
@import './marketplace/post-offer/MarketplacePostOfferView';
|
||||||
|
@ -6,6 +6,8 @@ import { CatalogLayouGuildCustomFurniView } from './guild-custom-furni/CatalogLa
|
|||||||
import { CatalogLayouGuildForumView } from './guild-forum/CatalogLayoutGuildForumView';
|
import { CatalogLayouGuildForumView } from './guild-forum/CatalogLayoutGuildForumView';
|
||||||
import { CatalogLayouGuildFrontpageView } from './guild-frontpage/CatalogLayoutGuildFrontpageView';
|
import { CatalogLayouGuildFrontpageView } from './guild-frontpage/CatalogLayoutGuildFrontpageView';
|
||||||
import { CatalogLayoutInfoLoyaltyView } from './info-loyalty/CatalogLayoutInfoLoyaltyView';
|
import { CatalogLayoutInfoLoyaltyView } from './info-loyalty/CatalogLayoutInfoLoyaltyView';
|
||||||
|
import { CatalogLayoutMarketplaceOwnItemsView } from './marketplace/own-items/CatalogLayoutMarketplaceOwnItemsView';
|
||||||
|
import { CatalogLayoutMarketplacePublicItemsView } from './marketplace/public-items/CatalogLayoutMarketplacePublicItemsView';
|
||||||
import { CatalogLayoutPetView } from './pets/CatalogLayoutPetView';
|
import { CatalogLayoutPetView } from './pets/CatalogLayoutPetView';
|
||||||
import { CatalogLayoutPets2View } from './pets2/CatalogLayoutPets2View';
|
import { CatalogLayoutPets2View } from './pets2/CatalogLayoutPets2View';
|
||||||
import { CatalogLayoutPets3View } from './pets3/CatalogLayoutPets3View';
|
import { CatalogLayoutPets3View } from './pets3/CatalogLayoutPets3View';
|
||||||
@ -41,9 +43,9 @@ export const GetCatalogLayout = (pageParser: CatalogPageMessageParser, roomPrevi
|
|||||||
case 'club_gifts':
|
case 'club_gifts':
|
||||||
return null;
|
return null;
|
||||||
case 'marketplace_own_items':
|
case 'marketplace_own_items':
|
||||||
return null;
|
return <CatalogLayoutMarketplaceOwnItemsView roomPreviewer={ roomPreviewer } pageParser={ pageParser } />;
|
||||||
case 'marketplace':
|
case 'marketplace':
|
||||||
return null;
|
return <CatalogLayoutMarketplacePublicItemsView roomPreviewer={ roomPreviewer } pageParser={ pageParser } />;
|
||||||
case 'single_bundle':
|
case 'single_bundle':
|
||||||
return <CatalogLayoutSingleBundleView roomPreviewer={ roomPreviewer } pageParser={ pageParser } />;
|
return <CatalogLayoutSingleBundleView roomPreviewer={ roomPreviewer } pageParser={ pageParser } />;
|
||||||
case 'spaces_new':
|
case 'spaces_new':
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
export interface IMarketplaceSearchOptions {
|
||||||
|
query: string;
|
||||||
|
type: number;
|
||||||
|
minPrice: number;
|
||||||
|
maxPrice: number;
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
export class MarketplaceConfirmType
|
||||||
|
{
|
||||||
|
public static readonly PURCHASE_CONFIRM_TYPE_NORMAL = 1;
|
||||||
|
public static readonly PURCHASE_CONFIRM_TYPE_HIGHER = 2;
|
||||||
|
public static readonly PURCHASE_CONFIRM_TYPE_INVALID = 3;
|
||||||
|
}
|
@ -0,0 +1,128 @@
|
|||||||
|
import { IObjectData } from '@nitrots/nitro-renderer';
|
||||||
|
|
||||||
|
export class MarketplaceOfferData
|
||||||
|
{
|
||||||
|
public static readonly TYPE_FLOOR: number = 1;
|
||||||
|
public static readonly TYPE_WALL: number = 2;
|
||||||
|
|
||||||
|
private _offerId: number;
|
||||||
|
private _furniId: number;
|
||||||
|
private _furniType: number;
|
||||||
|
private _extraData: string;
|
||||||
|
private _stuffData: IObjectData;
|
||||||
|
private _price: number;
|
||||||
|
private _averagePrice: number;
|
||||||
|
private _imageCallback: number;
|
||||||
|
private _status: number;
|
||||||
|
private _timeLeftMinutes: number = -1;
|
||||||
|
private _offerCount: number;
|
||||||
|
private _image: string;
|
||||||
|
|
||||||
|
constructor(offerId: number, furniId: number, furniType: number, extraData: string, stuffData: IObjectData, price: number, status: number, averagePrice: number, offerCount: number = -1)
|
||||||
|
{
|
||||||
|
this._offerId = offerId;
|
||||||
|
this._furniId = furniId;
|
||||||
|
this._furniType = furniType;
|
||||||
|
this._extraData = extraData;
|
||||||
|
this._stuffData = stuffData;
|
||||||
|
this._price = price;
|
||||||
|
this._status = status;
|
||||||
|
this._averagePrice = averagePrice;
|
||||||
|
this._offerCount = offerCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get offerId(): number
|
||||||
|
{
|
||||||
|
return this._offerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set offerId(offerId: number)
|
||||||
|
{
|
||||||
|
this._offerId = offerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get furniId(): number
|
||||||
|
{
|
||||||
|
return this._furniId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get furniType(): number
|
||||||
|
{
|
||||||
|
return this._furniType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get extraData(): string
|
||||||
|
{
|
||||||
|
return this._extraData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get stuffData(): IObjectData
|
||||||
|
{
|
||||||
|
return this._stuffData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get price(): number
|
||||||
|
{
|
||||||
|
return this._price;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set price(price: number)
|
||||||
|
{
|
||||||
|
this._price = price;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get averagePrice(): number
|
||||||
|
{
|
||||||
|
return this._averagePrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get image(): string
|
||||||
|
{
|
||||||
|
return this._image;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set image(image: string)
|
||||||
|
{
|
||||||
|
this._image = image;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get imageCallback(): number
|
||||||
|
{
|
||||||
|
return this._imageCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set imageCallback(callback: number)
|
||||||
|
{
|
||||||
|
this._imageCallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get status(): number
|
||||||
|
{
|
||||||
|
return this._status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get timeLeftMinutes(): number
|
||||||
|
{
|
||||||
|
return this._timeLeftMinutes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set timeLeftMinutes(minutes: number)
|
||||||
|
{
|
||||||
|
this._timeLeftMinutes = minutes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get offerCount(): number
|
||||||
|
{
|
||||||
|
return this._offerCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set offerCount(count: number)
|
||||||
|
{
|
||||||
|
this._offerCount = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get isUniqueLimitedItem(): boolean
|
||||||
|
{
|
||||||
|
return (this.stuffData && (this.stuffData.uniqueSeries > 0));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
export class MarketPlaceOfferState
|
||||||
|
{
|
||||||
|
public static readonly ONGOING = 1;
|
||||||
|
public static readonly ONGOING_OWN = 1;
|
||||||
|
public static readonly SOLD = 2;
|
||||||
|
public static readonly EXPIRED = 3;
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
export class MarketplaceSearchType
|
||||||
|
{
|
||||||
|
public static readonly BY_ACTIVITY = 1;
|
||||||
|
public static readonly BY_VALUE = 2;
|
||||||
|
public static readonly ADVANCED = 3;
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
.marketplace-item {
|
||||||
|
max-height: 70px;
|
||||||
|
height: 70px;
|
||||||
|
}
|
@ -0,0 +1,101 @@
|
|||||||
|
import { FC, useCallback } from 'react';
|
||||||
|
import { GetRoomEngine, LocalizeText } from '../../../../../../../api';
|
||||||
|
import { NitroCardGridItemView } from '../../../../../../../layout';
|
||||||
|
import { MarketplaceOfferData } from '../common/MarketplaceOfferData';
|
||||||
|
import { MarketPlaceOfferState } from '../common/MarketplaceOfferState';
|
||||||
|
|
||||||
|
export const OWN_OFFER = 1;
|
||||||
|
export const PUBLIC_OFFER = 2;
|
||||||
|
|
||||||
|
export interface MarketplaceItemViewProps
|
||||||
|
{
|
||||||
|
offerData: MarketplaceOfferData;
|
||||||
|
type?: number;
|
||||||
|
onClick(offerData: MarketplaceOfferData): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const MarketplaceItemView: FC<MarketplaceItemViewProps> = props =>
|
||||||
|
{
|
||||||
|
const { offerData = null, type = PUBLIC_OFFER, onClick = null } = props;
|
||||||
|
|
||||||
|
const getImageUrlForOffer = useCallback( () =>
|
||||||
|
{
|
||||||
|
if(!offerData) return '';
|
||||||
|
|
||||||
|
switch(offerData.furniType)
|
||||||
|
{
|
||||||
|
case MarketplaceOfferData.TYPE_FLOOR:
|
||||||
|
return GetRoomEngine().getFurnitureFloorIconUrl(offerData.furniId);
|
||||||
|
case MarketplaceOfferData.TYPE_WALL:
|
||||||
|
return GetRoomEngine().getFurnitureWallIconUrl(offerData.furniId, offerData.extraData);
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}, [offerData]);
|
||||||
|
|
||||||
|
const getMarketplaceOfferTitle = useCallback(() =>
|
||||||
|
{
|
||||||
|
if(!offerData) return '';
|
||||||
|
|
||||||
|
const localizationKey = offerData.furniType === 2 ? 'wallItem.name.' + offerData.furniId: 'roomItem.name.' + offerData.furniId;
|
||||||
|
|
||||||
|
return LocalizeText(localizationKey);
|
||||||
|
}, [offerData]);
|
||||||
|
|
||||||
|
const getMarketplaceOfferDescription = useCallback( () =>
|
||||||
|
{
|
||||||
|
if(!offerData) return '';
|
||||||
|
|
||||||
|
const localizationKey = offerData.furniType === 2 ? 'wallItem.desc.' + offerData.furniId : 'roomItem.desc.' + offerData.furniId;
|
||||||
|
|
||||||
|
return LocalizeText(localizationKey);
|
||||||
|
}, [offerData]);
|
||||||
|
|
||||||
|
const offerTime = useCallback( () =>
|
||||||
|
{
|
||||||
|
if(!offerData) return '';
|
||||||
|
|
||||||
|
if(offerData.status === MarketPlaceOfferState.SOLD) return LocalizeText('catalog.marketplace.offer.sold');
|
||||||
|
|
||||||
|
if(offerData.timeLeftMinutes <= 0) return LocalizeText('catalog.marketplace.offer.expired');
|
||||||
|
|
||||||
|
const time = Math.max(1, offerData.timeLeftMinutes);
|
||||||
|
const hours = Math.floor(time / 60);
|
||||||
|
const minutes = time - (hours * 60);
|
||||||
|
|
||||||
|
let text = minutes + ' ' + LocalizeText('catalog.marketplace.offer.minutes');
|
||||||
|
if(hours > 0)
|
||||||
|
{
|
||||||
|
text = hours + ' ' + LocalizeText('catalog.marketplace.offer.hours') + ' ' + text;
|
||||||
|
}
|
||||||
|
|
||||||
|
return LocalizeText('catalog.marketplace.offer.time_left', ['time'], [text] );
|
||||||
|
}, [offerData]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<NitroCardGridItemView className='w-100 marketplace-item align-items-center'>
|
||||||
|
<img src={ getImageUrlForOffer() } className='mx-3' alt='' />
|
||||||
|
<div className='h-100 flex-grow-1 justify-content-center '>
|
||||||
|
<div className='fw-bold'>{getMarketplaceOfferTitle()}</div>
|
||||||
|
<div className='fst-italic fs-6'>{getMarketplaceOfferDescription()}</div>
|
||||||
|
|
||||||
|
{ type === OWN_OFFER && <>
|
||||||
|
<div>{ LocalizeText('catalog.marketplace.offer.price_own_item', ['price'], [offerData.price.toString()])}</div>
|
||||||
|
<div>{ offerTime() }</div>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
{ type === PUBLIC_OFFER && <>
|
||||||
|
<div>{ LocalizeText('catalog.marketplace.offer.price_public_item', ['price', 'average'], [offerData.price.toString(), offerData.averagePrice.toString() ]) }</div>
|
||||||
|
<div>{ LocalizeText('catalog.marketplace.offer_count', ['count'], [offerData.offerCount.toString()]) }</div>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div className='btn-group-vertical mx-1 gap-2'>
|
||||||
|
{ (type === OWN_OFFER && offerData.status !== MarketPlaceOfferState.SOLD) && <button className='btn btn-secondary btn-sm' onClick={ () => onClick(offerData) }>{ LocalizeText('catalog.marketplace.offer.pick') }</button>}
|
||||||
|
{ type === PUBLIC_OFFER && <>
|
||||||
|
<button className='btn btn-secondary btn-sm' onClick={ () => onClick(offerData) } >{ LocalizeText('buy') }</button>
|
||||||
|
<button className='btn btn-secondary btn-sm' disabled={true}>{ LocalizeText('catalog.marketplace.view_more') }</button>
|
||||||
|
</>}
|
||||||
|
</div>
|
||||||
|
</NitroCardGridItemView>)
|
||||||
|
}
|
@ -0,0 +1,120 @@
|
|||||||
|
import { CancelMarketplaceOfferMessageComposer, GetMarketplaceOwnOffersMessageComposer, MarketplaceCancelOfferResultEvent, MarketplaceOwnOffersEvent, RedeemMarketplaceOfferCreditsMessageComposer } from '@nitrots/nitro-renderer';
|
||||||
|
import { FC, useCallback, useState } from 'react';
|
||||||
|
import { LocalizeText } from '../../../../../../../api';
|
||||||
|
import { BatchUpdates, CreateMessageHook, SendMessageHook, UseMountEffect } from '../../../../../../../hooks';
|
||||||
|
import { NitroCardGridView } from '../../../../../../../layout';
|
||||||
|
import { NitroLayoutBase } from '../../../../../../../layout/base';
|
||||||
|
import { NotificationAlertType } from '../../../../../../notification-center/common/NotificationAlertType';
|
||||||
|
import { NotificationUtilities } from '../../../../../../notification-center/common/NotificationUtilities';
|
||||||
|
import { CatalogLayoutProps } from '../../CatalogLayout.types';
|
||||||
|
import { MarketplaceOfferData } from '../common/MarketplaceOfferData';
|
||||||
|
import { MarketPlaceOfferState } from '../common/MarketplaceOfferState';
|
||||||
|
import { MarketplaceItemView, OWN_OFFER } from '../marketplace-item/MarketplaceItemView';
|
||||||
|
|
||||||
|
export interface CatalogLayoutMarketplaceOwnItemsViewProps extends CatalogLayoutProps
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CatalogLayoutMarketplaceOwnItemsView: FC<CatalogLayoutMarketplaceOwnItemsViewProps> = props =>
|
||||||
|
{
|
||||||
|
const [ creditsWaiting, setCreditsWaiting ] = useState(0);
|
||||||
|
const [ offers, setOffers ] = useState(new Map<number, MarketplaceOfferData>());
|
||||||
|
|
||||||
|
UseMountEffect(() =>
|
||||||
|
{
|
||||||
|
SendMessageHook(new GetMarketplaceOwnOffersMessageComposer());
|
||||||
|
});
|
||||||
|
|
||||||
|
const onMarketPlaceOwnOffersEvent = useCallback((event: MarketplaceOwnOffersEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
if(!parser) return;
|
||||||
|
|
||||||
|
const latestOffers = new Map<number, MarketplaceOfferData>();
|
||||||
|
parser.offers.forEach(entry =>
|
||||||
|
{
|
||||||
|
const offerEntry = new MarketplaceOfferData(entry.offerId, entry.furniId, entry.furniType, entry.extraData, entry.stuffData, entry.price, entry.status, entry.averagePrice, entry.offerCount);
|
||||||
|
offerEntry.timeLeftMinutes = entry.timeLeftMinutes;
|
||||||
|
latestOffers.set(entry.offerId, offerEntry);
|
||||||
|
});
|
||||||
|
|
||||||
|
BatchUpdates(() =>
|
||||||
|
{
|
||||||
|
setCreditsWaiting(parser.creditsWaiting);
|
||||||
|
setOffers(latestOffers);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const onMarketplaceCancelOfferResultEvent = useCallback((event:MarketplaceCancelOfferResultEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
if(!parser) return;
|
||||||
|
|
||||||
|
if(!parser.success)
|
||||||
|
{
|
||||||
|
NotificationUtilities.simpleAlert(LocalizeText('catalog.marketplace.cancel_failed'), NotificationAlertType.DEFAULT, null, null, LocalizeText('catalog.marketplace.operation_failed.topic'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setOffers( prev =>
|
||||||
|
{
|
||||||
|
const newVal = new Map(prev);
|
||||||
|
newVal.delete(parser.offerId);
|
||||||
|
return newVal;
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
CreateMessageHook(MarketplaceOwnOffersEvent, onMarketPlaceOwnOffersEvent);
|
||||||
|
CreateMessageHook(MarketplaceCancelOfferResultEvent, onMarketplaceCancelOfferResultEvent);
|
||||||
|
|
||||||
|
const redeemSoldOffers = useCallback(() =>
|
||||||
|
{
|
||||||
|
setOffers(prev =>
|
||||||
|
{
|
||||||
|
const newVal = new Map(prev);
|
||||||
|
|
||||||
|
const idsToDelete = [];
|
||||||
|
|
||||||
|
for(const offer of newVal.values())
|
||||||
|
{
|
||||||
|
if(offer.status === MarketPlaceOfferState.SOLD)
|
||||||
|
{
|
||||||
|
idsToDelete.push(offer.offerId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(const offerId of idsToDelete)
|
||||||
|
{
|
||||||
|
newVal.delete(offerId);
|
||||||
|
}
|
||||||
|
return newVal;
|
||||||
|
})
|
||||||
|
|
||||||
|
SendMessageHook(new RedeemMarketplaceOfferCreditsMessageComposer());
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const takeItemBack = useCallback( (offerData: MarketplaceOfferData) =>
|
||||||
|
{
|
||||||
|
SendMessageHook(new CancelMarketplaceOfferMessageComposer(offerData.offerId));
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{ (creditsWaiting <= 0) && <NitroLayoutBase className='text-black'>{LocalizeText('catalog.marketplace.redeem.no_sold_items')}</NitroLayoutBase>}
|
||||||
|
|
||||||
|
{ (creditsWaiting > 0) && <NitroLayoutBase className='text-black'>{LocalizeText('catalog.marketplace.redeem.get_credits', ['count', 'credits'], [Array.from(offers.values()).filter(value => value.status === MarketPlaceOfferState.SOLD).length.toString(), creditsWaiting.toString()])}</NitroLayoutBase>}
|
||||||
|
|
||||||
|
<button className='btn btn-primary btn-sm mx-auto' disabled={creditsWaiting <= 0} onClick={redeemSoldOffers}>{LocalizeText('catalog.marketplace.offer.redeem')}</button>
|
||||||
|
|
||||||
|
<div className='text-black'>{LocalizeText('catalog.marketplace.items_found', ['count'], [offers.size.toString()])}</div>
|
||||||
|
<NitroCardGridView columns={1} className='text-black'>
|
||||||
|
{
|
||||||
|
Array.from(offers.values()).map( (entry, index) => <MarketplaceItemView key={ index } offerData={ entry } type={ OWN_OFFER } onClick={takeItemBack} />)
|
||||||
|
}
|
||||||
|
</NitroCardGridView>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
.nitro-marketplace-post-offer {
|
||||||
|
width: 300px;
|
||||||
|
height: 365px;
|
||||||
|
|
||||||
|
.item-image-container {
|
||||||
|
width: 75px;
|
||||||
|
height: 75px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,111 @@
|
|||||||
|
import { ImageResult, MakeOfferMessageComposer, Vector3d } from '@nitrots/nitro-renderer';
|
||||||
|
import { FC, useCallback, useState } from 'react';
|
||||||
|
import { GetRoomEngine, LocalizeText } from '../../../../../../../api';
|
||||||
|
import { FurnitureItem } from '../../../../../../../components/inventory/common/FurnitureItem';
|
||||||
|
import { CatalogPostMarketplaceOfferEvent } from '../../../../../../../events/catalog/CatalogPostMarketplaceOfferEvent';
|
||||||
|
import { SendMessageHook, useUiEvent } from '../../../../../../../hooks';
|
||||||
|
import { NitroCardContentView, NitroCardHeaderView, NitroCardView, NitroLayoutFlex } from '../../../../../../../layout';
|
||||||
|
import { NotificationUtilities } from '../../../../../../notification-center/common/NotificationUtilities';
|
||||||
|
|
||||||
|
export const MarketplacePostOfferView : FC<{}> = props =>
|
||||||
|
{
|
||||||
|
const [ item, setItem ] = useState<FurnitureItem>(null);
|
||||||
|
const [ askingPrice, setAskingPrice ] = useState(0);
|
||||||
|
|
||||||
|
const close = useCallback(() =>
|
||||||
|
{
|
||||||
|
setItem(null);
|
||||||
|
setAskingPrice(0);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const onCatalogPostMarketplaceOfferEvent = useCallback( (event: CatalogPostMarketplaceOfferEvent) =>
|
||||||
|
{
|
||||||
|
setItem(event.item);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useUiEvent(CatalogPostMarketplaceOfferEvent.POST_MARKETPLACE, onCatalogPostMarketplaceOfferEvent);
|
||||||
|
|
||||||
|
const getItemImage = useCallback( () =>
|
||||||
|
{
|
||||||
|
if(!item) return '';
|
||||||
|
|
||||||
|
let object: ImageResult;
|
||||||
|
|
||||||
|
if(!item.isWallItem)
|
||||||
|
{
|
||||||
|
object = GetRoomEngine().getFurnitureFloorImage(item.type, new Vector3d(90,0,0), 64, this, 4293848814, item.extra.toString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
object = GetRoomEngine().getFurnitureWallImage(item.type, new Vector3d(90,0,0), 64, this, 4293848814, item.extra.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(object)
|
||||||
|
{
|
||||||
|
const image = object.getImage();
|
||||||
|
|
||||||
|
if(image) return image.src;
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}, [item]);
|
||||||
|
|
||||||
|
const getFurniTitle = useCallback( () =>
|
||||||
|
{
|
||||||
|
if(!item) return '';
|
||||||
|
|
||||||
|
const localizationKey = item.isWallItem ? 'wallItem.name.' + item.type : 'roomItem.name.' + item.type;
|
||||||
|
|
||||||
|
return LocalizeText(localizationKey);
|
||||||
|
}, [item]);
|
||||||
|
|
||||||
|
const getFurniDescription = useCallback( () =>
|
||||||
|
{
|
||||||
|
if(!item) return '';
|
||||||
|
|
||||||
|
const localizationKey = item.isWallItem ? 'wallItem.desc.' + item.type : 'roomItem.desc.' + item.type;
|
||||||
|
|
||||||
|
return LocalizeText(localizationKey);
|
||||||
|
}, [item]);
|
||||||
|
|
||||||
|
const postItem = useCallback( () =>
|
||||||
|
{
|
||||||
|
if(isNaN(askingPrice) || askingPrice <= 0 || !item) return;
|
||||||
|
|
||||||
|
NotificationUtilities.confirm(LocalizeText('inventory.marketplace.confirm_offer.info', ['furniname', 'price'], [getFurniTitle(), askingPrice.toString()]), () =>
|
||||||
|
{
|
||||||
|
SendMessageHook(new MakeOfferMessageComposer(askingPrice, item.isWallItem ? 2 : 1, item.id));
|
||||||
|
setItem(null);
|
||||||
|
},
|
||||||
|
() => { setItem(null)}, null, null, LocalizeText('inventory.marketplace.confirm_offer.title'));
|
||||||
|
}, [askingPrice, getFurniTitle, item]);
|
||||||
|
|
||||||
|
return ( item &&
|
||||||
|
<NitroCardView uniqueKey="catalog-mp-post-offer" className="nitro-marketplace-post-offer" simple={ true }>
|
||||||
|
<NitroCardHeaderView headerText={ LocalizeText('inventory.marketplace.make_offer.title') } onCloseClick={ close } />
|
||||||
|
<NitroCardContentView className="text-black">
|
||||||
|
<NitroLayoutFlex>
|
||||||
|
<div className="item-image-container mx-3" style={{ backgroundImage: `url(${getItemImage()})` }} />
|
||||||
|
<div className='h-100 flex-grow-1 justify-content-center '>
|
||||||
|
<div className='fw-bold'>{getFurniTitle()}</div>
|
||||||
|
<div className='fs-6'>{getFurniDescription()}</div>
|
||||||
|
</div>
|
||||||
|
</NitroLayoutFlex>
|
||||||
|
<div className='mx-2 fst-italic text-break mb-3'>
|
||||||
|
{ LocalizeText('inventory.marketplace.make_offer.expiration_info') }
|
||||||
|
</div>
|
||||||
|
<div className="d-flex flex-row text-black mb-3">
|
||||||
|
<div className="mr-2 align-self-center fw-bold" style={ { whiteSpace: 'nowrap' } }>{ LocalizeText('inventory.marketplace.make_offer.price_request') }</div>
|
||||||
|
<input className="form-control form-control-sm" type="number" min={0} value={ askingPrice } onChange={ event => setAskingPrice(event.target.valueAsNumber) } />
|
||||||
|
</div>
|
||||||
|
<div className="alert alert-light" role="alert">
|
||||||
|
{ askingPrice <= 0 || isNaN(askingPrice) ? LocalizeText('inventory.marketplace.make_offer.min_price', ['minprice'], ['1']) : LocalizeText('inventory.marketplace.make_offer.final_price', ['commission', 'finalprice'], ['1', (askingPrice + 1).toString()])}
|
||||||
|
</div>
|
||||||
|
<div className="btn-group btn-group-sm mt-3" role="group">
|
||||||
|
<button className='btn btn-primary' disabled={askingPrice <= 0 || isNaN(askingPrice)} onClick={ postItem }>
|
||||||
|
{ LocalizeText('inventory.marketplace.make_offer.post') }
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</NitroCardContentView>
|
||||||
|
</NitroCardView>
|
||||||
|
)
|
||||||
|
}
|
@ -0,0 +1,166 @@
|
|||||||
|
import { BuyMarketplaceOfferMessageComposer, GetMarketplaceOffersMessageComposer, MarketplaceBuyOfferResultEvent, MarketPlaceOffersEvent } from '@nitrots/nitro-renderer';
|
||||||
|
import { FC, useCallback, useMemo, useState } from 'react';
|
||||||
|
import { LocalizeText } from '../../../../../../../api';
|
||||||
|
import { BatchUpdates, CreateMessageHook, SendMessageHook } from '../../../../../../../hooks';
|
||||||
|
import { NitroCardGridView } from '../../../../../../../layout';
|
||||||
|
import { NotificationAlertType } from '../../../../../../notification-center/common/NotificationAlertType';
|
||||||
|
import { NotificationUtilities } from '../../../../../../notification-center/common/NotificationUtilities';
|
||||||
|
import { GetCurrencyAmount } from '../../../../../../purse/common/CurrencyHelper';
|
||||||
|
import { CatalogLayoutProps } from '../../CatalogLayout.types';
|
||||||
|
import { IMarketplaceSearchOptions } from '../common/IMarketplaceSearchOptions';
|
||||||
|
import { MarketplaceOfferData } from '../common/MarketplaceOfferData';
|
||||||
|
import { MarketplaceSearchType } from '../common/MarketplaceSearchType';
|
||||||
|
import { MarketplaceItemView, PUBLIC_OFFER } from '../marketplace-item/MarketplaceItemView';
|
||||||
|
import { SearchFormView } from './SearchFormView';
|
||||||
|
|
||||||
|
const SORT_TYPES_VALUE = [1, 2];
|
||||||
|
const SORT_TYPES_ACTIVITY = [3, 4, 5, 6];
|
||||||
|
const SORT_TYPES_ADVANCED = [1, 2, 3, 4, 5, 6];
|
||||||
|
export interface CatalogLayoutMarketplacePublicItemsViewProps extends CatalogLayoutProps
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CatalogLayoutMarketplacePublicItemsView: FC<CatalogLayoutMarketplacePublicItemsViewProps> = props =>
|
||||||
|
{
|
||||||
|
const [ searchType, setSearchType ] = useState(MarketplaceSearchType.BY_ACTIVITY);
|
||||||
|
const [ totalItemsFound, setTotalItemsFound ] = useState(0);
|
||||||
|
const [ offers, setOffers ] = useState(new Map<number, MarketplaceOfferData>());
|
||||||
|
const [ lastSearch, setLastSearch ] = useState<IMarketplaceSearchOptions>({ minPrice: -1, maxPrice: -1, query: '', type: 3 });
|
||||||
|
|
||||||
|
const requestOffers = useCallback((options: IMarketplaceSearchOptions) =>
|
||||||
|
{
|
||||||
|
setLastSearch(options);
|
||||||
|
SendMessageHook(new GetMarketplaceOffersMessageComposer(options.minPrice, options.maxPrice, options.query, options.type))
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const getSortTypes = useMemo( () =>
|
||||||
|
{
|
||||||
|
switch(searchType)
|
||||||
|
{
|
||||||
|
case MarketplaceSearchType.BY_ACTIVITY:
|
||||||
|
return SORT_TYPES_ACTIVITY;
|
||||||
|
case MarketplaceSearchType.BY_VALUE:
|
||||||
|
return SORT_TYPES_VALUE;
|
||||||
|
case MarketplaceSearchType.ADVANCED:
|
||||||
|
return SORT_TYPES_ADVANCED;
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}, [searchType]);
|
||||||
|
|
||||||
|
const purchaseItem = useCallback((offerData: MarketplaceOfferData) =>
|
||||||
|
{
|
||||||
|
if(offerData.price > GetCurrencyAmount(-1))
|
||||||
|
{
|
||||||
|
NotificationUtilities.simpleAlert(LocalizeText('catalog.alert.notenough.credits.description'), NotificationAlertType.DEFAULT, null, null, LocalizeText('catalog.alert.notenough.title'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const offerId = offerData.offerId;
|
||||||
|
NotificationUtilities.confirm(LocalizeText('catalog.marketplace.confirm_header'), () =>
|
||||||
|
{
|
||||||
|
SendMessageHook(new BuyMarketplaceOfferMessageComposer(offerId));
|
||||||
|
},
|
||||||
|
null, null, null, LocalizeText('catalog.marketplace.confirm_title'));
|
||||||
|
},[]);
|
||||||
|
|
||||||
|
const onMarketPlaceOffersEvent = useCallback( (event: MarketPlaceOffersEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
if(!parser) return;
|
||||||
|
|
||||||
|
const latestOffers = new Map<number, MarketplaceOfferData>();
|
||||||
|
parser.offers.forEach(entry =>
|
||||||
|
{
|
||||||
|
const offerEntry = new MarketplaceOfferData(entry.offerId, entry.furniId, entry.furniType, entry.extraData, entry.stuffData, entry.price, entry.status, entry.averagePrice, entry.offerCount);
|
||||||
|
offerEntry.timeLeftMinutes = entry.timeLeftMinutes;
|
||||||
|
latestOffers.set(entry.offerId, offerEntry);
|
||||||
|
});
|
||||||
|
|
||||||
|
BatchUpdates(() =>
|
||||||
|
{
|
||||||
|
setTotalItemsFound(parser.totalItemsFound);
|
||||||
|
setOffers(latestOffers);
|
||||||
|
});
|
||||||
|
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const onMarketplaceBuyOfferResultEvent = useCallback( (event: MarketplaceBuyOfferResultEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
if(!parser) return;
|
||||||
|
|
||||||
|
switch(parser.result)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
requestOffers(lastSearch);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
setOffers(prev =>
|
||||||
|
{
|
||||||
|
const newVal = new Map(prev);
|
||||||
|
newVal.delete(parser.requestedOfferId);
|
||||||
|
return newVal;
|
||||||
|
});
|
||||||
|
NotificationUtilities.simpleAlert(LocalizeText('catalog.marketplace.not_available_header'), NotificationAlertType.DEFAULT, null, null, LocalizeText('catalog.marketplace.not_available_title'));
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
// our shit was updated
|
||||||
|
// todo: some dialogue modal
|
||||||
|
setOffers( prev =>
|
||||||
|
{
|
||||||
|
const newVal = new Map(prev);
|
||||||
|
|
||||||
|
const item = newVal.get(parser.requestedOfferId);
|
||||||
|
if(item)
|
||||||
|
{
|
||||||
|
item.offerId = parser.offerId;
|
||||||
|
item.price = parser.newPrice;
|
||||||
|
item.offerCount--;
|
||||||
|
newVal.set(item.offerId, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
newVal.delete(parser.requestedOfferId);
|
||||||
|
return newVal;
|
||||||
|
});
|
||||||
|
|
||||||
|
NotificationUtilities.confirm(LocalizeText('catalog.marketplace.confirm_higher_header') +
|
||||||
|
'\n' + LocalizeText('catalog.marketplace.confirm_price', ['price'], [parser.newPrice.toString()]), () =>
|
||||||
|
{
|
||||||
|
SendMessageHook(new BuyMarketplaceOfferMessageComposer(parser.offerId));
|
||||||
|
},
|
||||||
|
null, null, null, LocalizeText('catalog.marketplace.confirm_higher_title'));
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
NotificationUtilities.simpleAlert(LocalizeText('catalog.alert.notenough.credits.description'), NotificationAlertType.DEFAULT, null, null, LocalizeText('catalog.alert.notenough.title'));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}, [lastSearch, requestOffers]);
|
||||||
|
|
||||||
|
CreateMessageHook(MarketPlaceOffersEvent, onMarketPlaceOffersEvent);
|
||||||
|
CreateMessageHook(MarketplaceBuyOfferResultEvent, onMarketplaceBuyOfferResultEvent);
|
||||||
|
|
||||||
|
return (<>
|
||||||
|
<div className="btn-group" role="group">
|
||||||
|
<button type="button" className={`btn btn-primary ${searchType === MarketplaceSearchType.BY_ACTIVITY ? 'active' : ''}`} onClick={() => setSearchType(MarketplaceSearchType.BY_ACTIVITY)}>
|
||||||
|
{ LocalizeText('catalog.marketplace.search_by_activity') }
|
||||||
|
</button>
|
||||||
|
<button type="button" className={`btn btn-primary ${searchType === MarketplaceSearchType.BY_VALUE ? 'active' : ''}`} onClick={() => setSearchType(MarketplaceSearchType.BY_VALUE)}>
|
||||||
|
{ LocalizeText('catalog.marketplace.search_by_value') }
|
||||||
|
</button>
|
||||||
|
<button type="button" className={`btn btn-primary ${searchType === MarketplaceSearchType.ADVANCED ? 'active' : ''}`} onClick={() => setSearchType(MarketplaceSearchType.ADVANCED)}>
|
||||||
|
{ LocalizeText('catalog.marketplace.search_advanced') }
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<SearchFormView sortTypes={ getSortTypes } searchType={ searchType } onSearch={ requestOffers }/>
|
||||||
|
|
||||||
|
<div className='text-black'>{LocalizeText('catalog.marketplace.items_found', ['count'], [offers.size.toString()])}</div>
|
||||||
|
<NitroCardGridView columns={1} className='text-black'>
|
||||||
|
{
|
||||||
|
Array.from(offers.values()).map( (entry, index) => <MarketplaceItemView key={ index } offerData={ entry } type={ PUBLIC_OFFER } onClick={purchaseItem} />)
|
||||||
|
}
|
||||||
|
</NitroCardGridView>
|
||||||
|
</>);
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
import { FC, useCallback, useEffect, useState } from 'react';
|
||||||
|
import { LocalizeText } from '../../../../../../../api';
|
||||||
|
import { IMarketplaceSearchOptions } from '../common/IMarketplaceSearchOptions';
|
||||||
|
import { MarketplaceSearchType } from '../common/MarketplaceSearchType';
|
||||||
|
|
||||||
|
export interface SearchFormViewProps
|
||||||
|
{
|
||||||
|
searchType: number;
|
||||||
|
sortTypes: number[];
|
||||||
|
onSearch(options: IMarketplaceSearchOptions): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SearchFormView: FC<SearchFormViewProps> = props =>
|
||||||
|
{
|
||||||
|
const { searchType = null, sortTypes = null, onSearch = null } = props;
|
||||||
|
const [ sortType, setSortType ] = useState(sortTypes ? sortTypes[0] : 3); // first item of SORT_TYPES_ACTIVITY
|
||||||
|
const [ searchQuery, setSearchQuery ] = useState('');
|
||||||
|
const [ min, setMin ] = useState(0);
|
||||||
|
const [ max, setMax ] = useState(0);
|
||||||
|
|
||||||
|
const onSortTypeChange = useCallback((sortType: number) =>
|
||||||
|
{
|
||||||
|
setSortType(sortType);
|
||||||
|
if(searchType === MarketplaceSearchType.BY_ACTIVITY || searchType === MarketplaceSearchType.BY_VALUE)
|
||||||
|
onSearch({ minPrice: -1, maxPrice: -1, query: '', type: sortType });
|
||||||
|
}, [onSearch, searchType]);
|
||||||
|
|
||||||
|
const onClickSearch = useCallback(() =>
|
||||||
|
{
|
||||||
|
const minPrice = min > 0 ? min : -1;
|
||||||
|
const maxPrice = max > 0 ? max : -1;
|
||||||
|
|
||||||
|
onSearch({ minPrice: minPrice, maxPrice: maxPrice, type: sortType, query: searchQuery })
|
||||||
|
}, [max, min, onSearch, searchQuery, sortType]);
|
||||||
|
|
||||||
|
useEffect( () =>
|
||||||
|
{
|
||||||
|
if(!sortTypes || !sortTypes.length) return;
|
||||||
|
|
||||||
|
const sortType = sortTypes[0];
|
||||||
|
setSortType(sortType);
|
||||||
|
|
||||||
|
if(searchType === MarketplaceSearchType.BY_ACTIVITY || MarketplaceSearchType.BY_VALUE === searchType)
|
||||||
|
onSearch({ minPrice: -1, maxPrice: -1, query: '', type: sortType });
|
||||||
|
}, [onSearch, searchType, sortTypes]);
|
||||||
|
|
||||||
|
return (<>
|
||||||
|
<div className="d-flex flex-row text-black">
|
||||||
|
<div className="mr-2 align-self-center col-4" style={ { whiteSpace: 'nowrap' } }>{ LocalizeText('catalog.marketplace.sort_order') }</div>
|
||||||
|
<select className="form-control form-control-sm" value={sortType} onChange={ (event) => onSortTypeChange(parseInt(event.target.value)) }>
|
||||||
|
{ sortTypes.map( (type, index) => <option key={index} value={type}>{ LocalizeText(`catalog.marketplace.sort.${type}`) }</option>)}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
{ searchType === MarketplaceSearchType.ADVANCED && <>
|
||||||
|
<div className="d-flex flex-row text-black">
|
||||||
|
<div className="mr-2 align-self-center col-4" style={ { whiteSpace: 'nowrap' } }>{ LocalizeText('catalog.marketplace.search_name') }</div>
|
||||||
|
<input className="form-control form-control-sm" type="text" value={ searchQuery} onChange={event => setSearchQuery(event.target.value)}/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="d-flex flex-row text-black">
|
||||||
|
<div className="mr-2 align-self-center col-4" style={ { whiteSpace: 'nowrap' } }>{ LocalizeText('catalog.marketplace.search_price') }</div>
|
||||||
|
<input className="form-control form-control-sm" type="number" min={0} value={ min } onChange={ event => setMin(event.target.valueAsNumber) } />
|
||||||
|
<input className="form-control form-control-sm" type="number" min={0} value={ max } onChange={ event => setMax(event.target.valueAsNumber) } />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button className="btn btn-secondary btn-sm float-end mx-auto" onClick={onClickSearch}>{ LocalizeText('generic.search') }</button>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
</>);
|
||||||
|
}
|
@ -1,13 +1,14 @@
|
|||||||
import { CfhSanctionMessageEvent, CfhTopicsInitEvent, IssueDeletedMessageEvent, IssueInfoMessageEvent, IssuePickFailedMessageEvent, ModeratorActionResultMessageEvent, ModeratorInitMessageEvent, ModeratorToolPreferencesEvent, RoomEngineEvent } from '@nitrots/nitro-renderer';
|
import { CfhSanctionMessageEvent, CfhTopicsInitEvent, IssueDeletedMessageEvent, IssueInfoMessageEvent, IssuePickFailedMessageEvent, ModeratorActionResultMessageEvent, ModeratorInitMessageEvent, ModeratorToolPreferencesEvent, RoomEngineEvent } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback } from 'react';
|
import { FC, useCallback } from 'react';
|
||||||
import { MODTOOLS_NEW_TICKET, PlaySound } from '../../api/utils/PlaySound';
|
import { MODTOOLS_NEW_TICKET, PlaySound } from '../../api/utils/PlaySound';
|
||||||
import { NotificationAlertEvent } from '../../events';
|
|
||||||
import { ModToolsEvent } from '../../events/mod-tools/ModToolsEvent';
|
import { ModToolsEvent } from '../../events/mod-tools/ModToolsEvent';
|
||||||
import { ModToolsOpenRoomChatlogEvent } from '../../events/mod-tools/ModToolsOpenRoomChatlogEvent';
|
import { ModToolsOpenRoomChatlogEvent } from '../../events/mod-tools/ModToolsOpenRoomChatlogEvent';
|
||||||
import { ModToolsOpenRoomInfoEvent } from '../../events/mod-tools/ModToolsOpenRoomInfoEvent';
|
import { ModToolsOpenRoomInfoEvent } from '../../events/mod-tools/ModToolsOpenRoomInfoEvent';
|
||||||
import { ModToolsOpenUserChatlogEvent } from '../../events/mod-tools/ModToolsOpenUserChatlogEvent';
|
import { ModToolsOpenUserChatlogEvent } from '../../events/mod-tools/ModToolsOpenUserChatlogEvent';
|
||||||
import { ModToolsOpenUserInfoEvent } from '../../events/mod-tools/ModToolsOpenUserInfoEvent';
|
import { ModToolsOpenUserInfoEvent } from '../../events/mod-tools/ModToolsOpenUserInfoEvent';
|
||||||
import { CreateMessageHook, dispatchUiEvent, useRoomEngineEvent, useUiEvent } from '../../hooks';
|
import { CreateMessageHook, useRoomEngineEvent, useUiEvent } from '../../hooks';
|
||||||
|
import { NotificationAlertType } from '../notification-center/common/NotificationAlertType';
|
||||||
|
import { NotificationUtilities } from '../notification-center/common/NotificationUtilities';
|
||||||
import { SetCfhCategories } from './common/GetCFHCategories';
|
import { SetCfhCategories } from './common/GetCFHCategories';
|
||||||
import { useModToolsContext } from './context/ModToolsContext';
|
import { useModToolsContext } from './context/ModToolsContext';
|
||||||
import { ModToolsActions } from './reducers/ModToolsReducer';
|
import { ModToolsActions } from './reducers/ModToolsReducer';
|
||||||
@ -38,8 +39,7 @@ export const ModToolsMessageHandler: FC<{}> = props =>
|
|||||||
tickets: data.issues
|
tickets: data.issues
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(parser);
|
|
||||||
}, [dispatchModToolsState]);
|
}, [dispatchModToolsState]);
|
||||||
|
|
||||||
const onIssueInfoMessageEvent = useCallback((event: IssueInfoMessageEvent) =>
|
const onIssueInfoMessageEvent = useCallback((event: IssueInfoMessageEvent) =>
|
||||||
@ -68,7 +68,6 @@ export const ModToolsMessageHandler: FC<{}> = props =>
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(parser);
|
|
||||||
}, [dispatchModToolsState, tickets]);
|
}, [dispatchModToolsState, tickets]);
|
||||||
|
|
||||||
const onModeratorToolPreferencesEvent = useCallback((event: ModeratorToolPreferencesEvent) =>
|
const onModeratorToolPreferencesEvent = useCallback((event: ModeratorToolPreferencesEvent) =>
|
||||||
@ -77,7 +76,6 @@ export const ModToolsMessageHandler: FC<{}> = props =>
|
|||||||
|
|
||||||
if(!parser) return;
|
if(!parser) return;
|
||||||
|
|
||||||
console.log(parser);
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const onIssuePickFailedMessageEvent = useCallback((event: IssuePickFailedMessageEvent) =>
|
const onIssuePickFailedMessageEvent = useCallback((event: IssuePickFailedMessageEvent) =>
|
||||||
@ -86,8 +84,7 @@ export const ModToolsMessageHandler: FC<{}> = props =>
|
|||||||
|
|
||||||
if(!parser) return;
|
if(!parser) return;
|
||||||
|
|
||||||
// todo: let user know it failed
|
NotificationUtilities.simpleAlert('Failed to pick issue', NotificationAlertType.DEFAULT, null, null, 'Error')
|
||||||
dispatchUiEvent(new NotificationAlertEvent(['Failed to pick issue'], null, null, null, 'Error', null));
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const onIssueDeletedMessageEvent = useCallback((event: IssueDeletedMessageEvent) =>
|
const onIssueDeletedMessageEvent = useCallback((event: IssueDeletedMessageEvent) =>
|
||||||
@ -119,11 +116,11 @@ export const ModToolsMessageHandler: FC<{}> = props =>
|
|||||||
|
|
||||||
if(parser.success)
|
if(parser.success)
|
||||||
{
|
{
|
||||||
dispatchUiEvent(new NotificationAlertEvent(['Moderation action was successfull'], null, null, null, 'Success', null));
|
NotificationUtilities.simpleAlert('Moderation action was successfull', NotificationAlertType.MODERATION, null, null, 'Success');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dispatchUiEvent(new NotificationAlertEvent(['There was a problem applying that moderation action'], null, null, null, 'Error', null));
|
NotificationUtilities.simpleAlert('There was a problem applying tht moderation action', NotificationAlertType.MODERATION, null, null, 'Error');
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@ -144,7 +141,6 @@ export const ModToolsMessageHandler: FC<{}> = props =>
|
|||||||
|
|
||||||
SetCfhCategories(categories);
|
SetCfhCategories(categories);
|
||||||
|
|
||||||
console.log(parser);
|
|
||||||
}, [dispatchModToolsState]);
|
}, [dispatchModToolsState]);
|
||||||
|
|
||||||
const onCfhSanctionMessageEvent = useCallback((event: CfhSanctionMessageEvent) =>
|
const onCfhSanctionMessageEvent = useCallback((event: CfhSanctionMessageEvent) =>
|
||||||
@ -153,7 +149,7 @@ export const ModToolsMessageHandler: FC<{}> = props =>
|
|||||||
|
|
||||||
if(!parser) return;
|
if(!parser) return;
|
||||||
|
|
||||||
console.log(parser);
|
// todo: update sanction data
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
CreateMessageHook(ModeratorInitMessageEvent, onModeratorInitMessageEvent);
|
CreateMessageHook(ModeratorInitMessageEvent, onModeratorInitMessageEvent);
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import { CallForHelpTopicData, DefaultSanctionMessageComposer, ModAlertMessageComposer, ModBanMessageComposer, ModKickMessageComposer, ModMessageMessageComposer, ModMuteMessageComposer, ModTradingLockMessageComposer } from '@nitrots/nitro-renderer';
|
import { CallForHelpTopicData, DefaultSanctionMessageComposer, ModAlertMessageComposer, ModBanMessageComposer, ModKickMessageComposer, ModMessageMessageComposer, ModMuteMessageComposer, ModTradingLockMessageComposer } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback, useMemo, useState } from 'react';
|
import { FC, useCallback, useMemo, useState } from 'react';
|
||||||
import { LocalizeText } from '../../../../../api';
|
import { LocalizeText } from '../../../../../api';
|
||||||
import { NotificationAlertEvent } from '../../../../../events';
|
import { SendMessageHook } from '../../../../../hooks';
|
||||||
import { dispatchUiEvent, SendMessageHook } from '../../../../../hooks';
|
|
||||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout';
|
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout';
|
||||||
|
import { NotificationAlertType } from '../../../../notification-center/common/NotificationAlertType';
|
||||||
|
import { NotificationUtilities } from '../../../../notification-center/common/NotificationUtilities';
|
||||||
import { useModToolsContext } from '../../../context/ModToolsContext';
|
import { useModToolsContext } from '../../../context/ModToolsContext';
|
||||||
import { ModActionDefinition } from '../../../utils/ModActionDefinition';
|
import { ModActionDefinition } from '../../../utils/ModActionDefinition';
|
||||||
import { ModToolsUserModActionViewProps } from './ModToolsUserModActionView.types';
|
import { ModToolsUserModActionViewProps } from './ModToolsUserModActionView.types';
|
||||||
@ -59,13 +60,13 @@ export const ModToolsUserModActionView: FC<ModToolsUserModActionViewProps> = pro
|
|||||||
{
|
{
|
||||||
if( (selectedTopic === -1) || (selectedAction === -1) )
|
if( (selectedTopic === -1) || (selectedAction === -1) )
|
||||||
{
|
{
|
||||||
dispatchUiEvent(new NotificationAlertEvent(['You must select a CFH topic and Sanction'], null, null, null, 'Error', null));
|
NotificationUtilities.simpleAlert('You must select a CFH topic and Sanction', NotificationAlertType.DEFAULT, null, null, 'Error');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!settings || !settings.cfhPermission)
|
if(!settings || !settings.cfhPermission)
|
||||||
{
|
{
|
||||||
dispatchUiEvent(new NotificationAlertEvent(['You do not have permission to do this'], null, null, null, 'Error', null));
|
NotificationUtilities.simpleAlert('You do not have permission to do this', NotificationAlertType.DEFAULT, null, null, 'Error');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,13 +75,13 @@ export const ModToolsUserModActionView: FC<ModToolsUserModActionViewProps> = pro
|
|||||||
|
|
||||||
if(!category)
|
if(!category)
|
||||||
{
|
{
|
||||||
dispatchUiEvent(new NotificationAlertEvent(['You must select a CFH topic'], null, null, null, 'Error', null));
|
NotificationUtilities.simpleAlert('You must select a CFH topic', NotificationAlertType.DEFAULT, null, null, 'Error');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!sanction)
|
if(!sanction)
|
||||||
{
|
{
|
||||||
dispatchUiEvent(new NotificationAlertEvent(['You must select a sanction'], null, null, null, 'Error', null));
|
NotificationUtilities.simpleAlert('You must select a sanction', NotificationAlertType.DEFAULT, null, null, 'Error');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,13 +93,13 @@ export const ModToolsUserModActionView: FC<ModToolsUserModActionViewProps> = pro
|
|||||||
|
|
||||||
if(!settings.alertPermission)
|
if(!settings.alertPermission)
|
||||||
{
|
{
|
||||||
dispatchUiEvent(new NotificationAlertEvent(['You have insufficient permissions.'], null, null, null, 'Error', null));
|
NotificationUtilities.simpleAlert('You have insufficient permissions', NotificationAlertType.DEFAULT, null, null, 'Error');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(message.trim().length === 0)
|
if(message.trim().length === 0)
|
||||||
{
|
{
|
||||||
dispatchUiEvent(new NotificationAlertEvent(['Please write a message to user.'], null, null, null, 'Error', null));
|
NotificationUtilities.simpleAlert('Please write a message to user', NotificationAlertType.DEFAULT, null, null, 'Error');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,7 +114,7 @@ export const ModToolsUserModActionView: FC<ModToolsUserModActionViewProps> = pro
|
|||||||
|
|
||||||
if(!settings.banPermission)
|
if(!settings.banPermission)
|
||||||
{
|
{
|
||||||
dispatchUiEvent(new NotificationAlertEvent(['You have insufficient permissions.'], null, null, null, 'Error', null));
|
NotificationUtilities.simpleAlert('You have insufficient permissions', NotificationAlertType.DEFAULT, null, null, 'Error');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,7 +126,7 @@ export const ModToolsUserModActionView: FC<ModToolsUserModActionViewProps> = pro
|
|||||||
|
|
||||||
if(!settings.kickPermission)
|
if(!settings.kickPermission)
|
||||||
{
|
{
|
||||||
dispatchUiEvent(new NotificationAlertEvent(['You have insufficient permissions.'], null, null, null, 'Error', null));
|
NotificationUtilities.simpleAlert('You have insufficient permissions', NotificationAlertType.DEFAULT, null, null, 'Error');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,7 +145,7 @@ export const ModToolsUserModActionView: FC<ModToolsUserModActionViewProps> = pro
|
|||||||
|
|
||||||
if(message.trim().length === 0)
|
if(message.trim().length === 0)
|
||||||
{
|
{
|
||||||
dispatchUiEvent(new NotificationAlertEvent(['Please write a message to user.'], null, null, null, 'Error', null));
|
NotificationUtilities.simpleAlert('Please write a message to user', NotificationAlertType.DEFAULT, null, null, 'Error');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,20 +1,23 @@
|
|||||||
import { FC, ReactNode, useCallback, useMemo, useState } from 'react';
|
import { FC, ReactNode, useCallback, useMemo, useState } from 'react';
|
||||||
import { createPortal } from 'react-dom';
|
import { createPortal } from 'react-dom';
|
||||||
import { NotificationAlertEvent } from '../../events';
|
import { NotificationAlertEvent, NotificationConfirmEvent } from '../../events';
|
||||||
import { NotificationBubbleEvent } from '../../events/notification-center/NotificationBubbleEvent';
|
import { NotificationBubbleEvent } from '../../events/notification-center/NotificationBubbleEvent';
|
||||||
import { useUiEvent } from '../../hooks/events';
|
import { useUiEvent } from '../../hooks/events';
|
||||||
import { NotificationAlertItem } from './common/NotificationAlertItem';
|
import { NotificationAlertItem } from './common/NotificationAlertItem';
|
||||||
import { NotificationBubbleItem } from './common/NotificationBubbleItem';
|
import { NotificationBubbleItem } from './common/NotificationBubbleItem';
|
||||||
import { NotificationBubbleType } from './common/NotificationBubbleType';
|
import { NotificationBubbleType } from './common/NotificationBubbleType';
|
||||||
|
import { NotificationConfirmItem } from './common/NotificationConfirmItem';
|
||||||
import { NotificationCenterMessageHandler } from './NotificationCenterMessageHandler';
|
import { NotificationCenterMessageHandler } from './NotificationCenterMessageHandler';
|
||||||
import { NotificationCenterViewProps } from './NotificationCenterView.types';
|
import { NotificationCenterViewProps } from './NotificationCenterView.types';
|
||||||
import { GetAlertLayout } from './views/alert-layouts/GetAlertLayout';
|
import { GetAlertLayout } from './views/alert-layouts/GetAlertLayout';
|
||||||
import { GetBubbleLayout } from './views/bubble-layouts/GetBubbleLayout';
|
import { GetBubbleLayout } from './views/bubble-layouts/GetBubbleLayout';
|
||||||
|
import { GetConfirmLayout } from './views/confirm-layouts/GetConfirmLayout';
|
||||||
|
|
||||||
export const NotificationCenterView: FC<NotificationCenterViewProps> = props =>
|
export const NotificationCenterView: FC<NotificationCenterViewProps> = props =>
|
||||||
{
|
{
|
||||||
const [ alerts, setAlerts ] = useState<NotificationAlertItem[]>([]);
|
const [ alerts, setAlerts ] = useState<NotificationAlertItem[]>([]);
|
||||||
const [ bubbleAlerts, setBubbleAlerts ] = useState<NotificationBubbleItem[]>([]);
|
const [ bubbleAlerts, setBubbleAlerts ] = useState<NotificationBubbleItem[]>([]);
|
||||||
|
const [ confirms, setConfirms ] = useState<NotificationConfirmItem[]>([]);
|
||||||
|
|
||||||
const onNotificationAlertEvent = useCallback((event: NotificationAlertEvent) =>
|
const onNotificationAlertEvent = useCallback((event: NotificationAlertEvent) =>
|
||||||
{
|
{
|
||||||
@ -36,6 +39,15 @@ export const NotificationCenterView: FC<NotificationCenterViewProps> = props =>
|
|||||||
|
|
||||||
useUiEvent(NotificationBubbleEvent.NEW_BUBBLE, onNotificationBubbleEvent);
|
useUiEvent(NotificationBubbleEvent.NEW_BUBBLE, onNotificationBubbleEvent);
|
||||||
|
|
||||||
|
const onNotificationConfirmEvent = useCallback((event: NotificationConfirmEvent) =>
|
||||||
|
{
|
||||||
|
const confirmItem = new NotificationConfirmItem(event.type, event.message, event.onConfirm, event.onCancel, event.confirmText, event.cancelText, event.title);
|
||||||
|
|
||||||
|
setConfirms(prevValue => [ confirmItem, ...prevValue ]);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useUiEvent(NotificationConfirmEvent.CONFIRM, onNotificationConfirmEvent);
|
||||||
|
|
||||||
const closeAlert = useCallback((alert: NotificationAlertItem) =>
|
const closeAlert = useCallback((alert: NotificationAlertItem) =>
|
||||||
{
|
{
|
||||||
setAlerts(prevValue =>
|
setAlerts(prevValue =>
|
||||||
@ -62,6 +74,19 @@ export const NotificationCenterView: FC<NotificationCenterViewProps> = props =>
|
|||||||
})
|
})
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const closeConfirm = useCallback((item: NotificationConfirmItem) =>
|
||||||
|
{
|
||||||
|
setConfirms(prevValue =>
|
||||||
|
{
|
||||||
|
const newConfirms = [ ...prevValue ];
|
||||||
|
const index = newConfirms.findIndex(value => (item === value));
|
||||||
|
|
||||||
|
if(index >= 0) newConfirms.splice(index, 1);
|
||||||
|
|
||||||
|
return newConfirms;
|
||||||
|
})
|
||||||
|
}, []);
|
||||||
|
|
||||||
const getAlerts = useMemo(() =>
|
const getAlerts = useMemo(() =>
|
||||||
{
|
{
|
||||||
if(!alerts || !alerts.length) return null;
|
if(!alerts || !alerts.length) return null;
|
||||||
@ -101,6 +126,22 @@ export const NotificationCenterView: FC<NotificationCenterViewProps> = props =>
|
|||||||
return elements;
|
return elements;
|
||||||
}, [ bubbleAlerts, closeBubbleAlert ]);
|
}, [ bubbleAlerts, closeBubbleAlert ]);
|
||||||
|
|
||||||
|
const getConfirms = useMemo(() =>
|
||||||
|
{
|
||||||
|
if(!confirms || !confirms.length) return null;
|
||||||
|
|
||||||
|
const elements: ReactNode[] = [];
|
||||||
|
|
||||||
|
for(const confirm of confirms)
|
||||||
|
{
|
||||||
|
const element = GetConfirmLayout(confirm, () => closeConfirm(confirm));
|
||||||
|
|
||||||
|
elements.push(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
return elements;
|
||||||
|
}, [ confirms, closeConfirm ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<NotificationCenterMessageHandler />
|
<NotificationCenterMessageHandler />
|
||||||
@ -108,6 +149,7 @@ export const NotificationCenterView: FC<NotificationCenterViewProps> = props =>
|
|||||||
{ getBubbleAlerts }
|
{ getBubbleAlerts }
|
||||||
</div>
|
</div>
|
||||||
{ createPortal(getAlerts, document.getElementById('nitro-alerts-container')) }
|
{ createPortal(getAlerts, document.getElementById('nitro-alerts-container')) }
|
||||||
|
{ createPortal(getConfirms, document.getElementById('nitro-confirms-container')) }
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,67 @@
|
|||||||
|
export class NotificationConfirmItem
|
||||||
|
{
|
||||||
|
private static ITEM_ID: number = -1;
|
||||||
|
|
||||||
|
private _id: number;
|
||||||
|
private _confirmType: string;
|
||||||
|
private _message: string;
|
||||||
|
private _onConfirm: Function;
|
||||||
|
private _onCancel: Function;
|
||||||
|
private _confirmText: string;
|
||||||
|
private _cancelText: string;
|
||||||
|
private _title: string;
|
||||||
|
|
||||||
|
constructor(confirmType: string, message: string, onConfirm: Function, onCancel: Function, confirmText: string, cancelText: string, title: string)
|
||||||
|
{
|
||||||
|
NotificationConfirmItem.ITEM_ID += 1;
|
||||||
|
|
||||||
|
this._id = NotificationConfirmItem.ITEM_ID;
|
||||||
|
this._confirmType = confirmType;
|
||||||
|
this._message = message;
|
||||||
|
this._onConfirm = onConfirm;
|
||||||
|
this._onCancel = onCancel;
|
||||||
|
this._confirmText = confirmText;
|
||||||
|
this._cancelText = cancelText;
|
||||||
|
this._title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get id(): number
|
||||||
|
{
|
||||||
|
return this._id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get confirmType(): string
|
||||||
|
{
|
||||||
|
return this._confirmType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get message(): string
|
||||||
|
{
|
||||||
|
return this._message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get onConfirm(): Function
|
||||||
|
{
|
||||||
|
return this._onConfirm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get onCancel(): Function
|
||||||
|
{
|
||||||
|
return this._onCancel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get confirmText(): string
|
||||||
|
{
|
||||||
|
return this._confirmText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get cancelText(): string
|
||||||
|
{
|
||||||
|
return this._cancelText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get title(): string
|
||||||
|
{
|
||||||
|
return this._title;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
export class NotificationConfirmType
|
||||||
|
{
|
||||||
|
public static DEFAULT: string = 'default';
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
import { HabboWebTools, RoomEnterEffect } from '@nitrots/nitro-renderer';
|
import { HabboWebTools, RoomEnterEffect } from '@nitrots/nitro-renderer';
|
||||||
import { CreateLinkEvent, GetConfiguration, GetNitroInstance, LocalizeText } from '../../../api';
|
import { CreateLinkEvent, GetConfiguration, GetNitroInstance, LocalizeText } from '../../../api';
|
||||||
import { NotificationAlertEvent } from '../../../events';
|
import { NotificationAlertEvent, NotificationConfirmEvent } from '../../../events';
|
||||||
import { NotificationBubbleEvent } from '../../../events/notification-center/NotificationBubbleEvent';
|
import { NotificationBubbleEvent } from '../../../events/notification-center/NotificationBubbleEvent';
|
||||||
import { dispatchUiEvent } from '../../../hooks';
|
import { dispatchUiEvent } from '../../../hooks';
|
||||||
import { CatalogPageName } from '../../catalog/common/CatalogPageName';
|
import { CatalogPageName } from '../../catalog/common/CatalogPageName';
|
||||||
@ -112,7 +112,18 @@ export class NotificationUtilities
|
|||||||
dispatchUiEvent(new NotificationAlertEvent(messages, NotificationAlertType.MOTD, null, null, LocalizeText('notifications.motd.title')));
|
dispatchUiEvent(new NotificationAlertEvent(messages, NotificationAlertType.MOTD, null, null, LocalizeText('notifications.motd.title')));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static simpleAlert(message: string, type: string = null, clickUrl: string = null, clickUrlText: string = null, title: string = null, imageUrl: string = null): void
|
public static confirm(message: string, onConfirm: Function, onCancel: Function, confirmText: string = null, cancelText: string = null, title: string = null, type: string = null): void
|
||||||
|
{
|
||||||
|
if(!confirmText || !confirmText.length) confirmText = LocalizeText('generic.confirm');
|
||||||
|
|
||||||
|
if(!cancelText || !cancelText.length) cancelText = LocalizeText('generic.cancel');
|
||||||
|
|
||||||
|
if(!title || !title.length) title = LocalizeText('notifications.broadcast.title');
|
||||||
|
|
||||||
|
dispatchUiEvent(new NotificationConfirmEvent(type, this.cleanText(message), onConfirm, onCancel, confirmText, cancelText, title));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static simpleAlert(message: string, type: string, clickUrl: string = null, clickUrlText: string = null, title: string = null, imageUrl: string = null): void
|
||||||
{
|
{
|
||||||
if(!title || !title.length) title = LocalizeText('notifications.broadcast.title');
|
if(!title || !title.length) title = LocalizeText('notifications.broadcast.title');
|
||||||
|
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
import { NotificationConfirmItem } from '../../common/NotificationConfirmItem';
|
||||||
|
import { NotificationDefaultConfirmView } from './default/NotificationDefaultConfirmView';
|
||||||
|
|
||||||
|
export const GetConfirmLayout = (item: NotificationConfirmItem, close: () => void) =>
|
||||||
|
{
|
||||||
|
if(!item) return null;
|
||||||
|
|
||||||
|
const props = { key: item.id, item, close };
|
||||||
|
|
||||||
|
switch(item.confirmType)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
return <NotificationDefaultConfirmView { ...props } />
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
import { NotificationConfirmItem } from '../../common/NotificationConfirmItem';
|
||||||
|
|
||||||
|
export interface NotificationConfirmLayoutViewProps
|
||||||
|
{
|
||||||
|
item: NotificationConfirmItem;
|
||||||
|
close: () => void;
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
import { DetailsHTMLAttributes, FC } from 'react';
|
||||||
|
import { NotificationAlertView } from '../../../../../layout';
|
||||||
|
import { NotificationConfirmLayoutViewProps } from '../NotificationConfirmLayoutView.types';
|
||||||
|
|
||||||
|
export interface NotificationDefaultConfirmViewProps extends NotificationConfirmLayoutViewProps, DetailsHTMLAttributes<HTMLDivElement>
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export const NotificationDefaultConfirmView: FC<NotificationDefaultConfirmViewProps> = props =>
|
||||||
|
{
|
||||||
|
const { item = null, close = null, ...rest } = props;
|
||||||
|
const { message = null, onConfirm = null, onCancel = null, confirmText = null, cancelText = null, title = null } = item;
|
||||||
|
|
||||||
|
const confirm = () =>
|
||||||
|
{
|
||||||
|
if(onConfirm) onConfirm();
|
||||||
|
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
const cancel = () =>
|
||||||
|
{
|
||||||
|
if(onCancel) onCancel();
|
||||||
|
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<NotificationAlertView title={ title } close={ close } { ...rest }>
|
||||||
|
{ message }
|
||||||
|
<div className="d-flex justify-content-between align-items-center">
|
||||||
|
<button type="button" className="btn btn-danger" onClick={ cancel }>{ cancelText }</button>
|
||||||
|
<button type="button" className="btn btn-primary" onClick={ confirm }>{ confirmText }</button>
|
||||||
|
</div>
|
||||||
|
</NotificationAlertView>
|
||||||
|
);
|
||||||
|
}
|
@ -48,7 +48,7 @@ export const AvatarInfoUseProductConfirmView: FC<AvatarInfoUseProductConfirmView
|
|||||||
|
|
||||||
switch(furniData.specialType)
|
switch(furniData.specialType)
|
||||||
{
|
{
|
||||||
case FurniCategory._Str_7696: {
|
case FurniCategory.PET_SHAMPOO: {
|
||||||
if(customParts.length < 2) return null;
|
if(customParts.length < 2) return null;
|
||||||
|
|
||||||
const currentPalette = GetRoomEngine().getPetColorResult(petIndex, petFigureData.paletteId);
|
const currentPalette = GetRoomEngine().getPetColorResult(petIndex, petFigureData.paletteId);
|
||||||
@ -68,7 +68,7 @@ export const AvatarInfoUseProductConfirmView: FC<AvatarInfoUseProductConfirmView
|
|||||||
|
|
||||||
return <PetImageView typeId={ petFigureData.typeId } paletteId={ paletteId } color={ petFigureData.color } customParts={ petFigureData.customParts } direction={ 2 } />
|
return <PetImageView typeId={ petFigureData.typeId } paletteId={ paletteId } color={ petFigureData.color } customParts={ petFigureData.customParts } direction={ 2 } />
|
||||||
}
|
}
|
||||||
case FurniCategory._Str_7297: {
|
case FurniCategory.PET_CUSTOM_PART: {
|
||||||
if(customParts.length < 4) return null;
|
if(customParts.length < 4) return null;
|
||||||
|
|
||||||
const newCustomParts: PetCustomPart[] = [];
|
const newCustomParts: PetCustomPart[] = [];
|
||||||
@ -95,7 +95,7 @@ export const AvatarInfoUseProductConfirmView: FC<AvatarInfoUseProductConfirmView
|
|||||||
|
|
||||||
return <PetImageView typeId={ petFigureData.typeId } paletteId={ petFigureData.paletteId } color={ petFigureData.color } customParts={ newCustomParts } direction={ 2 } />;
|
return <PetImageView typeId={ petFigureData.typeId } paletteId={ petFigureData.paletteId } color={ petFigureData.color } customParts={ newCustomParts } direction={ 2 } />;
|
||||||
}
|
}
|
||||||
case FurniCategory._Str_7954: {
|
case FurniCategory.PET_CUSTOM_PART_SHAMPOO: {
|
||||||
if(customParts.length < 3) return null;
|
if(customParts.length < 3) return null;
|
||||||
|
|
||||||
const newCustomParts: PetCustomPart[] = [];
|
const newCustomParts: PetCustomPart[] = [];
|
||||||
@ -121,7 +121,7 @@ export const AvatarInfoUseProductConfirmView: FC<AvatarInfoUseProductConfirmView
|
|||||||
|
|
||||||
return <PetImageView typeId={ petFigureData.typeId } paletteId={ petFigureData.paletteId } color={ petFigureData.color } customParts={ newCustomParts } direction={ 2 } />;
|
return <PetImageView typeId={ petFigureData.typeId } paletteId={ petFigureData.paletteId } color={ petFigureData.color } customParts={ newCustomParts } direction={ 2 } />;
|
||||||
}
|
}
|
||||||
case FurniCategory._Str_6096: {
|
case FurniCategory.PET_SADDLE: {
|
||||||
if(customParts.length < 4) return null;
|
if(customParts.length < 4) return null;
|
||||||
|
|
||||||
const newCustomParts: PetCustomPart[] = [];
|
const newCustomParts: PetCustomPart[] = [];
|
||||||
@ -149,9 +149,9 @@ export const AvatarInfoUseProductConfirmView: FC<AvatarInfoUseProductConfirmView
|
|||||||
|
|
||||||
return <PetImageView typeId={ petFigureData.typeId } paletteId={ petFigureData.paletteId } color={ petFigureData.color } customParts={ newCustomParts } direction={ 2 } />;
|
return <PetImageView typeId={ petFigureData.typeId } paletteId={ petFigureData.paletteId } color={ petFigureData.color } customParts={ newCustomParts } direction={ 2 } />;
|
||||||
}
|
}
|
||||||
case FurniCategory._Str_8726:
|
case FurniCategory.MONSTERPLANT_REBREED:
|
||||||
case FurniCategory._Str_6915:
|
case FurniCategory.MONSTERPLANT_REVIVAL:
|
||||||
case FurniCategory._Str_9449: {
|
case FurniCategory.MONSTERPLANT_FERTILIZE: {
|
||||||
let posture = 'rip';
|
let posture = 'rip';
|
||||||
|
|
||||||
const roomObject = GetRoomEngine().getRoomObject(roomSession.roomId, petData.roomIndex, RoomObjectCategory.UNIT);
|
const roomObject = GetRoomEngine().getRoomObject(roomSession.roomId, petData.roomIndex, RoomObjectCategory.UNIT);
|
||||||
@ -190,25 +190,25 @@ export const AvatarInfoUseProductConfirmView: FC<AvatarInfoUseProductConfirmView
|
|||||||
|
|
||||||
switch(furniData.specialType)
|
switch(furniData.specialType)
|
||||||
{
|
{
|
||||||
case FurniCategory._Str_7696:
|
case FurniCategory.PET_SHAMPOO:
|
||||||
mode = _Str_11906;
|
mode = _Str_11906;
|
||||||
break;
|
break;
|
||||||
case FurniCategory._Str_7297:
|
case FurniCategory.PET_CUSTOM_PART:
|
||||||
mode = _Str_11214;
|
mode = _Str_11214;
|
||||||
break;
|
break;
|
||||||
case FurniCategory._Str_7954:
|
case FurniCategory.PET_CUSTOM_PART_SHAMPOO:
|
||||||
mode = _Str_11733;
|
mode = _Str_11733;
|
||||||
break;
|
break;
|
||||||
case FurniCategory._Str_6096:
|
case FurniCategory.PET_SADDLE:
|
||||||
mode = _Str_11369;
|
mode = _Str_11369;
|
||||||
break;
|
break;
|
||||||
case FurniCategory._Str_6915:
|
case FurniCategory.MONSTERPLANT_REVIVAL:
|
||||||
mode = _Str_8759;
|
mode = _Str_8759;
|
||||||
break;
|
break;
|
||||||
case FurniCategory._Str_8726:
|
case FurniCategory.MONSTERPLANT_REBREED:
|
||||||
mode = _Str_8432;
|
mode = _Str_8432;
|
||||||
break;
|
break;
|
||||||
case FurniCategory._Str_9449:
|
case FurniCategory.MONSTERPLANT_FERTILIZE:
|
||||||
mode = _Str_9653;
|
mode = _Str_9653;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -8,14 +8,14 @@ import { ContextMenuHeaderView } from '../../../context-menu/views/header/Contex
|
|||||||
import { ContextMenuListItemView } from '../../../context-menu/views/list-item/ContextMenuListItemView';
|
import { ContextMenuListItemView } from '../../../context-menu/views/list-item/ContextMenuListItemView';
|
||||||
import { AvatarInfoUseProductViewProps } from './AvatarInfoUseProductView.types';
|
import { AvatarInfoUseProductViewProps } from './AvatarInfoUseProductView.types';
|
||||||
|
|
||||||
const _Str_2906: number = 0;
|
const PRODUCT_PAGE_UKNOWN: number = 0;
|
||||||
const _Str_13718: number = 1;
|
const PRODUCT_PAGE_SHAMPOO: number = 1;
|
||||||
const _Str_14146: number = 2;
|
const PRODUCT_PAGE_CUSTOM_PART: number = 2;
|
||||||
const _Str_15667: number = 3;
|
const PRODUCT_PAGE_CUSTOM_PART_SHAMPOO: number = 3;
|
||||||
const _Str_14658: number = 4;
|
const PRODUCT_PAGE_SADDLE: number = 4;
|
||||||
const _Str_14165: number = 5;
|
const PRODUCT_PAGE_REVIVE: number = 5;
|
||||||
const _Str_12577: number = 6;
|
const PRODUCT_PAGE_REBREED: number = 6;
|
||||||
const _Str_14611: number = 7;
|
const PRODUCT_PAGE_FERTILIZE: number = 7;
|
||||||
|
|
||||||
export const AvatarInfoUseProductView: FC<AvatarInfoUseProductViewProps> = props =>
|
export const AvatarInfoUseProductView: FC<AvatarInfoUseProductViewProps> = props =>
|
||||||
{
|
{
|
||||||
@ -31,30 +31,30 @@ export const AvatarInfoUseProductView: FC<AvatarInfoUseProductViewProps> = props
|
|||||||
|
|
||||||
if(!furniData) return;
|
if(!furniData) return;
|
||||||
|
|
||||||
let mode = _Str_2906;
|
let mode = PRODUCT_PAGE_UKNOWN;
|
||||||
|
|
||||||
switch(furniData.specialType)
|
switch(furniData.specialType)
|
||||||
{
|
{
|
||||||
case FurniCategory._Str_7696:
|
case FurniCategory.PET_SHAMPOO:
|
||||||
mode = _Str_13718;
|
mode = PRODUCT_PAGE_SHAMPOO;
|
||||||
break;
|
break;
|
||||||
case FurniCategory._Str_7297:
|
case FurniCategory.PET_CUSTOM_PART:
|
||||||
mode = _Str_14146;
|
mode = PRODUCT_PAGE_CUSTOM_PART;
|
||||||
break;
|
break;
|
||||||
case FurniCategory._Str_7954:
|
case FurniCategory.PET_CUSTOM_PART_SHAMPOO:
|
||||||
mode = _Str_15667;
|
mode = PRODUCT_PAGE_CUSTOM_PART_SHAMPOO;
|
||||||
break;
|
break;
|
||||||
case FurniCategory._Str_6096:
|
case FurniCategory.PET_SADDLE:
|
||||||
mode = _Str_14658;
|
mode = PRODUCT_PAGE_SADDLE;
|
||||||
break;
|
break;
|
||||||
case FurniCategory._Str_6915:
|
case FurniCategory.MONSTERPLANT_REVIVAL:
|
||||||
mode = _Str_14165;
|
mode = PRODUCT_PAGE_REVIVE;
|
||||||
break;
|
break;
|
||||||
case FurniCategory._Str_8726:
|
case FurniCategory.MONSTERPLANT_REBREED:
|
||||||
mode = _Str_12577;
|
mode = PRODUCT_PAGE_REBREED;
|
||||||
break;
|
break;
|
||||||
case FurniCategory._Str_9449:
|
case FurniCategory.MONSTERPLANT_FERTILIZE:
|
||||||
mode = _Str_14611;
|
mode = PRODUCT_PAGE_FERTILIZE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,23 +86,23 @@ export const AvatarInfoUseProductView: FC<AvatarInfoUseProductViewProps> = props
|
|||||||
<ContextMenuHeaderView>
|
<ContextMenuHeaderView>
|
||||||
{ item.name }
|
{ item.name }
|
||||||
</ContextMenuHeaderView>
|
</ContextMenuHeaderView>
|
||||||
{ (mode === _Str_2906) &&
|
{ (mode === PRODUCT_PAGE_UKNOWN) &&
|
||||||
<ContextMenuListItemView onClick={ event => processAction('use_product') }>
|
<ContextMenuListItemView onClick={ event => processAction('use_product') }>
|
||||||
{ LocalizeText('infostand.button.useproduct') }
|
{ LocalizeText('infostand.button.useproduct') }
|
||||||
</ContextMenuListItemView> }
|
</ContextMenuListItemView> }
|
||||||
{ (mode === _Str_13718) &&
|
{ (mode === PRODUCT_PAGE_SHAMPOO) &&
|
||||||
<ContextMenuListItemView onClick={ event => processAction('use_product_shampoo') }>
|
<ContextMenuListItemView onClick={ event => processAction('use_product_shampoo') }>
|
||||||
{ LocalizeText('infostand.button.useproduct_shampoo') }
|
{ LocalizeText('infostand.button.useproduct_shampoo') }
|
||||||
</ContextMenuListItemView> }
|
</ContextMenuListItemView> }
|
||||||
{ (mode === _Str_14146) &&
|
{ (mode === PRODUCT_PAGE_CUSTOM_PART) &&
|
||||||
<ContextMenuListItemView onClick={ event => processAction('use_product_custom_part') }>
|
<ContextMenuListItemView onClick={ event => processAction('use_product_custom_part') }>
|
||||||
{ LocalizeText('infostand.button.useproduct_custom_part') }
|
{ LocalizeText('infostand.button.useproduct_custom_part') }
|
||||||
</ContextMenuListItemView> }
|
</ContextMenuListItemView> }
|
||||||
{ (mode === _Str_15667) &&
|
{ (mode === PRODUCT_PAGE_CUSTOM_PART_SHAMPOO) &&
|
||||||
<ContextMenuListItemView onClick={ event => processAction('use_product_custom_part_shampoo') }>
|
<ContextMenuListItemView onClick={ event => processAction('use_product_custom_part_shampoo') }>
|
||||||
{ LocalizeText('infostand.button.useproduct_custom_part_shampoo') }
|
{ LocalizeText('infostand.button.useproduct_custom_part_shampoo') }
|
||||||
</ContextMenuListItemView> }
|
</ContextMenuListItemView> }
|
||||||
{ (mode === _Str_14658) &&
|
{ (mode === PRODUCT_PAGE_SADDLE) &&
|
||||||
<>
|
<>
|
||||||
{ item.replace &&
|
{ item.replace &&
|
||||||
<ContextMenuListItemView onClick={ event => processAction('replace_product_saddle') }>
|
<ContextMenuListItemView onClick={ event => processAction('replace_product_saddle') }>
|
||||||
@ -113,15 +113,15 @@ export const AvatarInfoUseProductView: FC<AvatarInfoUseProductViewProps> = props
|
|||||||
{ LocalizeText('infostand.button.useproduct_saddle') }
|
{ LocalizeText('infostand.button.useproduct_saddle') }
|
||||||
</ContextMenuListItemView> }
|
</ContextMenuListItemView> }
|
||||||
</> }
|
</> }
|
||||||
{ (mode === _Str_14165) &&
|
{ (mode === PRODUCT_PAGE_REVIVE) &&
|
||||||
<ContextMenuListItemView onClick={ event => processAction('revive_monsterplant') }>
|
<ContextMenuListItemView onClick={ event => processAction('revive_monsterplant') }>
|
||||||
{ LocalizeText('infostand.button.revive_monsterplant') }
|
{ LocalizeText('infostand.button.revive_monsterplant') }
|
||||||
</ContextMenuListItemView> }
|
</ContextMenuListItemView> }
|
||||||
{ (mode === _Str_12577) &&
|
{ (mode === PRODUCT_PAGE_REBREED) &&
|
||||||
<ContextMenuListItemView onClick={ event => processAction('rebreed_monsterplant') }>
|
<ContextMenuListItemView onClick={ event => processAction('rebreed_monsterplant') }>
|
||||||
{ LocalizeText('infostand.button.rebreed_monsterplant') }
|
{ LocalizeText('infostand.button.rebreed_monsterplant') }
|
||||||
</ContextMenuListItemView> }
|
</ContextMenuListItemView> }
|
||||||
{ (mode === _Str_14611) &&
|
{ (mode === PRODUCT_PAGE_FERTILIZE) &&
|
||||||
<ContextMenuListItemView onClick={ event => processAction('fertilize_monsterplant') }>
|
<ContextMenuListItemView onClick={ event => processAction('fertilize_monsterplant') }>
|
||||||
{ LocalizeText('infostand.button.fertilize_monsterplant') }
|
{ LocalizeText('infostand.button.fertilize_monsterplant') }
|
||||||
</ContextMenuListItemView> }
|
</ContextMenuListItemView> }
|
||||||
|
@ -43,7 +43,7 @@ export const PurchasableClothingConfirmView: FC<PurchasableClothingConfirmViewPr
|
|||||||
{
|
{
|
||||||
switch(furniData.specialType)
|
switch(furniData.specialType)
|
||||||
{
|
{
|
||||||
case FurniCategory._Str_12534:
|
case FurniCategory.FIGURE_PURCHASABLE_SET:
|
||||||
mode = MODE_PURCHASABLE_CLOTHING;
|
mode = MODE_PURCHASABLE_CLOTHING;
|
||||||
|
|
||||||
const setIds = furniData.customParams.split(',').map(part => parseInt(part));
|
const setIds = furniData.customParams.split(',').map(part => parseInt(part));
|
||||||
|
Loading…
Reference in New Issue
Block a user