Badges work

This commit is contained in:
Bill 2021-04-29 13:36:37 -04:00
parent 656470f15d
commit 996c7f218e
7 changed files with 115 additions and 11 deletions

View File

@ -1,4 +1,6 @@
import { SetActivatedBadgesComposer } from 'nitro-renderer';
import { Reducer } from 'react'; import { Reducer } from 'react';
import { SendMessageHook } from '../../../hooks/messages/message-event';
export interface IInventoryBadgeState export interface IInventoryBadgeState
{ {
@ -24,6 +26,8 @@ export class InventoryBadgeActions
public static SET_NEEDS_UPDATE: string = 'IBDA_SET_NEEDS_UPDATE'; public static SET_NEEDS_UPDATE: string = 'IBDA_SET_NEEDS_UPDATE';
public static SET_BADGE: string = 'IBDA_SET_BADGE'; public static SET_BADGE: string = 'IBDA_SET_BADGE';
public static SET_BADGES: string = 'IBDA_SET_BADGES'; public static SET_BADGES: string = 'IBDA_SET_BADGES';
public static ADD_ACTIVE_BADGE: string = 'IBDA_ADD_ACTIVE_BADGE';
public static REMOVE_ACTIVE_BADGE: string = 'IBDA_REMOVE_ACTIVE_BADGE';
} }
export const initialInventoryBadge: IInventoryBadgeState = { export const initialInventoryBadge: IInventoryBadgeState = {
@ -66,12 +70,55 @@ export const inventoryBadgeReducer: Reducer<IInventoryBadgeState, IInventoryBadg
{ {
const wearingIndex = activeBadgeCodes.indexOf(badgeCode); const wearingIndex = activeBadgeCodes.indexOf(badgeCode);
if(wearingIndex === -1) badges.push(badgeCode); badges.push(badgeCode);
else activeBadges.push(badgeCode);
if(wearingIndex >= 0) activeBadges.push(badgeCode);
} }
return { ...state, badges, activeBadges }; return { ...state, badges, activeBadges };
} }
case InventoryBadgeActions.ADD_ACTIVE_BADGE: {
const badgeCode = action.payload.badgeCode;
if(state.activeBadges.indexOf(badgeCode) >= 0) return state;
const activeBadges = [ ...state.activeBadges ];
activeBadges.push(badgeCode);
const composer = new SetActivatedBadgesComposer();
for(const badgeCode of activeBadges)
{
composer.addActivatedBadge(badgeCode);
}
SendMessageHook(composer);
return { ...state, activeBadges };
}
case InventoryBadgeActions.REMOVE_ACTIVE_BADGE: {
const badgeCode = action.payload.badgeCode;
const index = state.activeBadges.indexOf(badgeCode);
if(index === -1) return state;
const activeBadges = [ ...state.activeBadges ];
activeBadges.splice(index, 1);
const composer = new SetActivatedBadgesComposer();
for(const badgeCode of activeBadges)
{
composer.addActivatedBadge(badgeCode);
}
SendMessageHook(composer);
return { ...state, activeBadges };
}
default: default:
return state; return state;
} }

View File

@ -6,6 +6,7 @@ import { LocalizeText } from '../../../../utils/LocalizeText';
import { BadgeImageView } from '../../../badge-image/BadgeImageView'; import { BadgeImageView } from '../../../badge-image/BadgeImageView';
import { useInventoryContext } from '../../context/InventoryContext'; import { useInventoryContext } from '../../context/InventoryContext';
import { InventoryBadgeActions } from '../../reducers/InventoryBadgeReducer'; import { InventoryBadgeActions } from '../../reducers/InventoryBadgeReducer';
import { InventoryActiveBadgeResultsView } from './active-results/InventoryActiveBadgeResultsView';
import { InventoryBadgeViewProps } from './InventoryBadgeView.types'; import { InventoryBadgeViewProps } from './InventoryBadgeView.types';
import { InventoryBadgeResultsView } from './results/InventoryBadgeResultsView'; import { InventoryBadgeResultsView } from './results/InventoryBadgeResultsView';
@ -39,29 +40,60 @@ export const InventoryBadgeView: FC<InventoryBadgeViewProps> = props =>
}, [ needsBadgeUpdate, badges, dispatchBadgeState ]); }, [ needsBadgeUpdate, badges, dispatchBadgeState ]);
useEffect(() => function isWearingBadge(badgeCode: string): boolean
{ {
// update current badge return (activeBadges.indexOf(badgeCode) >= 0);
}, [ badge ]); }
function canWearBadges(): boolean
{
return (activeBadges.length < 5);
}
function toggleBadge(): void
{
if(isWearingBadge(badge))
{
dispatchBadgeState({
type: InventoryBadgeActions.REMOVE_ACTIVE_BADGE,
payload: {
badgeCode: badge
}
});
}
else
{
if(!canWearBadges()) return;
dispatchBadgeState({
type: InventoryBadgeActions.ADD_ACTIVE_BADGE,
payload: {
badgeCode: badge
}
});
}
}
return ( return (
<> <>
<div className="row"> <div className="row">
<div className="col-7"> <div className="col-7">
<InventoryBadgeResultsView badges={ badges } cols={ 5 } /> <InventoryBadgeResultsView badges={ badges } activeBadges={ activeBadges } cols={ 5 } />
</div> </div>
<div className="col-5"> <div className="col-5">
<InventoryBadgeResultsView badges={ activeBadges } cols={ 3 } /> <p className="mb-1 text-black">{ LocalizeText('inventory.badges.activebadges') }</p>
<InventoryActiveBadgeResultsView badges={ activeBadges } />
</div> </div>
</div> </div>
{ badge && badge.length && { badge && badge.length &&
<div className="d-flex justify-content-between align-items-center bg-secondary rounded p-1 mb-1"> <div className="d-flex justify-content-between align-items-center bg-secondary rounded px-2 py-1 mb-1">
<div className="d-flex flex-grow-1 current-badge-container"> <div className="d-flex flex-grow-1 current-badge-container">
<BadgeImageView badgeCode={ badge } /> <BadgeImageView badgeCode={ badge } />
<div className="d-flex flex-column justify-content-center flex-grow-1 ms-2"> <div className="d-flex flex-column justify-content-center flex-grow-1 ms-2">
<p className="mb-0">{ LocalizeBadgeName(badge) }</p> <p className="mb-0">{ LocalizeBadgeName(badge) }</p>
</div> </div>
</div> </div>
<button type="button" className={ 'btn btn-' + (isWearingBadge(badge) ? 'danger' : 'success') } disabled={ !canWearBadges() } onClick={ toggleBadge }>{ LocalizeText(isWearingBadge(badge) ? 'inventory.badges.clearbadge' : 'inventory.badges.wearbadge')}</button>
</div> } </div> }
<div className="d-flex justify-content-center align-items-center bg-primary rounded p-1"> <div className="d-flex justify-content-center align-items-center bg-primary rounded p-1">
<div className="h6 m-0 text-white">{ LocalizeText('achievements_score_description', [ 'score' ], [ '0' ]) }</div> <div className="h6 m-0 text-white">{ LocalizeText('achievements_score_description', [ 'score' ], [ '0' ]) }</div>

View File

@ -0,0 +1,2 @@
.badge-item-container {
}

View File

@ -0,0 +1,17 @@
import { FC } from 'react';
import { InventoryBadgeItemView } from '../item/InventoryBadgeItemView';
import { InventoryActiveBadgeResultsViewProps } from './InventoryActiveBadgeResultsView.types';
export const InventoryActiveBadgeResultsView: FC<InventoryActiveBadgeResultsViewProps> = props =>
{
const { badges = [] } = props;
return (
<div className="row row-cols-3 align-content-start g-0">
{ (badges && badges.length && badges.map((code, index) =>
{
return <InventoryBadgeItemView key={ index } badge={ code } />
})) || null }
</div>
);
}

View File

@ -0,0 +1,4 @@
export interface InventoryActiveBadgeResultsViewProps
{
badges?: string[];
}

View File

@ -4,12 +4,14 @@ import { InventoryBadgeResultsViewProps } from './InventoryBadgeResultsView.type
export const InventoryBadgeResultsView: FC<InventoryBadgeResultsViewProps> = props => export const InventoryBadgeResultsView: FC<InventoryBadgeResultsViewProps> = props =>
{ {
const { badges = [], cols = 5 } = props; const { badges = [], activeBadges = [] } = props;
return ( return (
<div className={ 'row row-cols-' + cols + ' align-content-start g-0 badge-item-container' }> <div className="row row-cols-5 align-content-start g-0 badge-item-container">
{ (badges && badges.length && badges.map((code, index) => { (badges && badges.length && badges.map((code, index) =>
{ {
if(activeBadges.indexOf(code) >= 0) return null;
return <InventoryBadgeItemView key={ index } badge={ code } /> return <InventoryBadgeItemView key={ index } badge={ code } />
})) || null } })) || null }
</div> </div>

View File

@ -1,5 +1,5 @@
export interface InventoryBadgeResultsViewProps export interface InventoryBadgeResultsViewProps
{ {
badges: string[]; badges: string[];
cols?: number; activeBadges: string[];
} }