nitro-v36-with-renderer-v36
/
src /
components /
room /
widgets /
furniture /
FurnitureCraftingView.tsx
FurnitureCraftingView.tsx 9.1 Ko
Télécharger le fichier
import { GetRoomEngine, RoomObjectCategory } from '@octane/renderer';
import { FC, ReactElement, useEffect, useMemo, useState } from 'react';
import { IsOwnerOfFurniture, LocalizeText } from '../../../../api';
import {
AutoGrid,
Button,
Column,
LayoutGridItem,
LayoutLoadingSpinnerView,
OctaneCardContentView,
OctaneCardHeaderView,
OctaneCardView
} from '../../../../common';
import { useFurnitureCraftingWidget, useRoom } from '../../../../hooks';
import { BaseButton } from '../../../../common/BaseButton';
import '../../../../css/room/FurniWindowsCAir.css';
import { NativeTextTree } from '../../../../common/native-text/NativeTextTree';
export const FurnitureCraftingView: FC<{}> = (props) => {
const {
objectId = -1,
recipes = [],
ingredients = [],
selectedRecipe = null,
requiredIngredients = null,
isCrafting = false,
craft = null,
selectRecipe = null,
onClose = null
} = useFurnitureCraftingWidget();
const { roomSession = null } = useRoom();
const [waitingToConfirm, setWaitingToConfirm] = useState(false);
const isOwner = useMemo(() => {
const roomObject = GetRoomEngine().getRoomObject(roomSession.roomId, objectId, RoomObjectCategory.FLOOR);
return IsOwnerOfFurniture(roomObject);
}, [objectId, roomSession]);
const canCraft = useMemo(() => {
if (!requiredIngredients || !requiredIngredients.length) return false;
for (const ingredient of requiredIngredients) {
const ingredientData = ingredients.find((data) => data.name === ingredient.itemName);
if (!ingredientData || ingredientData.count < ingredient.count) return false;
}
return true;
}, [ingredients, requiredIngredients]);
const tryCraft = () => {
if (!waitingToConfirm) {
setWaitingToConfirm(true);
return;
}
craft();
setWaitingToConfirm(false);
};
useEffect(() => {
setWaitingToConfirm(false);
}, [selectedRecipe]);
if (objectId === -1) return null;
return (
<NativeTextTree>
<OctaneCardView className="octane-widget-crafting" theme="primary-slim">
<OctaneCardHeaderView headerText={LocalizeText('crafting.title')} onCloseClick={onClose} />
<OctaneCardContentView>
<div className="crafting-widget-layout flex grow! gap-2 overflow-hidden">
<div className="crafting-widget-pane flex flex-col w-full gap-2 min-w-0">
<Column fullHeight overflow="hidden">
<div className="octane-crafting__heading bg-muted rounded py-1 text-center">{LocalizeText('crafting.title.products')}</div>
<AutoGrid columnCount={5}>
{recipes.length > 0 &&
recipes.map((item) => (
<LayoutGridItem component={BaseButton} type="button"
key={item.name}
itemActive={selectedRecipe && selectedRecipe.name === item.name}
itemImage={item.iconUrl}
onClick={() => selectRecipe(item)}
/>
))}
</AutoGrid>
</Column>
<Column fullHeight overflow="hidden">
<div className="octane-crafting__heading bg-muted rounded py-1 text-center">{LocalizeText('crafting.title.mixer')}</div>
<AutoGrid columnCount={5}>
{ingredients.length > 0 &&
ingredients.map((item) => (
<LayoutGridItem
key={item.name}
className={(!item.count ? 'opacity-50 ' : '') + 'cursor-default'}
itemCount={item.count}
itemCountMinimum={0}
itemImage={item.iconUrl}
/>
))}
</AutoGrid>
</Column>
</div>
<div className="crafting-widget-pane flex flex-col w-full gap-2 min-w-0">
{!selectedRecipe && (
<Column center fullHeight className="octane-crafting__info text-black text-center">
{LocalizeText('crafting.info.start')}
</Column>
)}
{selectedRecipe && (
<>
<div className="flex flex-col h-full overflow-hidden">
<div className="octane-crafting__heading bg-muted rounded py-1 text-center">{LocalizeText('crafting.current_recipe')}</div>
<AutoGrid columnCount={5}>
{!!requiredIngredients &&
requiredIngredients.length > 0 &&
requiredIngredients.map((ingredient) => {
const ingredientData = ingredients.find((i) => i.name === ingredient.itemName);
const elements: ReactElement[] = [];
for (let i = 0; i < ingredient.count; i++) {
elements.push(
<LayoutGridItem
key={i}
className={(ingredientData.count - i <= 0 ? 'opacity-50 ' : '') + 'cursor-default'}
itemImage={ingredientData.iconUrl}
/>
);
}
return elements;
})}
</AutoGrid>
</div>
<div className="flex flex-col h-full gap-2">
<div className="flex flex-col h-full bg-muted rounded gap-2">
<div className="octane-crafting__heading py-1 text-center">{LocalizeText('crafting.result')}</div>
<div className="flex items-center justify-center flex-col h-full pb-1 gap-1">
<div className="flex flex-col h-full">
<img alt="" src={selectedRecipe.iconUrl} />
</div>
<div className="octane-crafting__info text-black">{selectedRecipe.localizedName}</div>
</div>
</div>
<Button
disabled={!isOwner || !canCraft || isCrafting}
variant={!isOwner || !canCraft ? 'danger' : waitingToConfirm ? 'warning' : isCrafting ? 'primary' : 'success'}
onClick={tryCraft}
>
{!isCrafting &&
LocalizeText(
!isOwner
? 'crafting.btn.notowner'
: !canCraft
? 'crafting.status.recipe.incomplete'
: waitingToConfirm
? 'generic.confirm'
: 'crafting.btn.craft'
)}
{isCrafting && <LayoutLoadingSpinnerView />}
</Button>
</div>
</>
)}
</div>
</div>
</OctaneCardContentView>
</OctaneCardView>
</NativeTextTree>
);
};
