From dd354e9e74cc1d4cba11ac6799f0a2b2cb841d22 Mon Sep 17 00:00:00 2001 From: Bill Date: Thu, 29 Apr 2021 04:05:36 -0400 Subject: [PATCH] Add badge inventory --- .../reducers/InventoryBadgeReducer.tsx | 78 +++++++++++++++++++ .../views/badge/InventoryBadgeView.scss | 9 +++ .../views/badge/InventoryBadgeView.tsx | 71 +++++++++++++++++ .../views/badge/InventoryBadgeView.types.ts | 3 + .../badge/item/InventoryBadgeItemView.scss | 17 ++++ .../badge/item/InventoryBadgeItemView.tsx | 33 ++++++++ .../item/InventoryBadgeItemView.types.ts | 4 + .../results/InventoryBadgeResultsView.scss | 5 ++ .../results/InventoryBadgeResultsView.tsx | 17 ++++ .../InventoryBadgeResultsView.types.ts | 5 ++ 10 files changed, 242 insertions(+) create mode 100644 src/views/inventory/reducers/InventoryBadgeReducer.tsx create mode 100644 src/views/inventory/views/badge/InventoryBadgeView.scss create mode 100644 src/views/inventory/views/badge/InventoryBadgeView.tsx create mode 100644 src/views/inventory/views/badge/InventoryBadgeView.types.ts create mode 100644 src/views/inventory/views/badge/item/InventoryBadgeItemView.scss create mode 100644 src/views/inventory/views/badge/item/InventoryBadgeItemView.tsx create mode 100644 src/views/inventory/views/badge/item/InventoryBadgeItemView.types.ts create mode 100644 src/views/inventory/views/badge/results/InventoryBadgeResultsView.scss create mode 100644 src/views/inventory/views/badge/results/InventoryBadgeResultsView.tsx create mode 100644 src/views/inventory/views/badge/results/InventoryBadgeResultsView.types.ts diff --git a/src/views/inventory/reducers/InventoryBadgeReducer.tsx b/src/views/inventory/reducers/InventoryBadgeReducer.tsx new file mode 100644 index 00000000..c110fd7c --- /dev/null +++ b/src/views/inventory/reducers/InventoryBadgeReducer.tsx @@ -0,0 +1,78 @@ +import { Reducer } from 'react'; + +export interface IInventoryBadgeState +{ + needsBadgeUpdate: boolean; + badge: string; + badges: string[]; + activeBadges: string[]; +} + +export interface IInventoryBadgeAction +{ + type: string; + payload: { + flag?: boolean; + badgeCode?: string; + badgeCodes?: string[]; + activeBadgeCodes?: string[]; + } +} + +export class InventoryBadgeActions +{ + public static SET_NEEDS_UPDATE: string = 'IBDA_SET_NEEDS_UPDATE'; + public static SET_BADGE: string = 'IBDA_SET_BADGE'; + public static SET_BADGES: string = 'IBDA_SET_BADGES'; +} + +export const initialInventoryBadge: IInventoryBadgeState = { + needsBadgeUpdate: true, + badge: null, + badges: [], + activeBadges: [] +} + +export const inventoryBadgeReducer: Reducer = (state, action) => +{ + switch(action.type) + { + case InventoryBadgeActions.SET_NEEDS_UPDATE: + return { ...state, needsBadgeUpdate: (action.payload.flag || false) }; + case InventoryBadgeActions.SET_BADGE: { + let badge = (action.payload.badgeCode || state.badge || null); + + let index = 0; + + if(badge) + { + const foundIndex = state.badges.indexOf(badge); + + if(foundIndex > -1) index = foundIndex; + } + + badge = (state.badges[index] || null); + + return { ...state, badge }; + } + case InventoryBadgeActions.SET_BADGES: { + const badges: string[] = []; + const activeBadges: string[] = []; + + const badgeCodes = action.payload.badgeCodes; + const activeBadgeCodes = action.payload.activeBadgeCodes; + + for(const badgeCode of badgeCodes) + { + const wearingIndex = activeBadgeCodes.indexOf(badgeCode); + + if(wearingIndex === -1) badges.push(badgeCode); + else activeBadges.push(badgeCode); + } + + return { ...state, badges, activeBadges }; + } + default: + return state; + } +} diff --git a/src/views/inventory/views/badge/InventoryBadgeView.scss b/src/views/inventory/views/badge/InventoryBadgeView.scss new file mode 100644 index 00000000..2631fabf --- /dev/null +++ b/src/views/inventory/views/badge/InventoryBadgeView.scss @@ -0,0 +1,9 @@ +.current-badge-container { + + .badge-image { + width: 45px; + height: 45px; + } +} +@import './item/InventoryBadgeItemView'; +@import './results/InventoryBadgeResultsView'; diff --git a/src/views/inventory/views/badge/InventoryBadgeView.tsx b/src/views/inventory/views/badge/InventoryBadgeView.tsx new file mode 100644 index 00000000..2f4d30cb --- /dev/null +++ b/src/views/inventory/views/badge/InventoryBadgeView.tsx @@ -0,0 +1,71 @@ +import { RequestBadgesComposer } from 'nitro-renderer'; +import { FC, useEffect } from 'react'; +import { SendMessageHook } from '../../../../hooks/messages/message-event'; +import { LocalizeBadgeName } from '../../../../utils/LocalizeBageName'; +import { LocalizeText } from '../../../../utils/LocalizeText'; +import { BadgeImageView } from '../../../badge-image/BadgeImageView'; +import { useInventoryContext } from '../../context/InventoryContext'; +import { InventoryBadgeActions } from '../../reducers/InventoryBadgeReducer'; +import { InventoryBadgeViewProps } from './InventoryBadgeView.types'; +import { InventoryBadgeResultsView } from './results/InventoryBadgeResultsView'; + +export const InventoryBadgeView: FC = props => +{ + const { badgeState = null, dispatchBadgeState = null } = useInventoryContext(); + const { needsBadgeUpdate = false, badge = null, badges = [], activeBadges = [] } = badgeState; + + useEffect(() => + { + if(needsBadgeUpdate) + { + dispatchBadgeState({ + type: InventoryBadgeActions.SET_NEEDS_UPDATE, + payload: { + flag: false + } + }); + + SendMessageHook(new RequestBadgesComposer()); + } + else + { + dispatchBadgeState({ + type: InventoryBadgeActions.SET_BADGE, + payload: { + badgeCode: null + } + }); + } + + }, [ needsBadgeUpdate, badges, dispatchBadgeState ]); + + useEffect(() => + { + // update current badge + }, [ badge ]); + + return ( + <> +
+
+ +
+
+ +
+
+ { badge && badge.length && +
+
+ +
+

{ LocalizeBadgeName(badge) }

+
+
+
} +
+
{ LocalizeText('achievements_score_description', [ 'score' ], [ '0' ]) }
+
+ + ); +} diff --git a/src/views/inventory/views/badge/InventoryBadgeView.types.ts b/src/views/inventory/views/badge/InventoryBadgeView.types.ts new file mode 100644 index 00000000..a089f548 --- /dev/null +++ b/src/views/inventory/views/badge/InventoryBadgeView.types.ts @@ -0,0 +1,3 @@ +export interface InventoryBadgeViewProps +{ +} diff --git a/src/views/inventory/views/badge/item/InventoryBadgeItemView.scss b/src/views/inventory/views/badge/item/InventoryBadgeItemView.scss new file mode 100644 index 00000000..cab746cb --- /dev/null +++ b/src/views/inventory/views/badge/item/InventoryBadgeItemView.scss @@ -0,0 +1,17 @@ +.inventory-badge-item-container { + height: 48px; + max-height: 48px; + + .inventory-badge-item { + width: 100%; + height: 100%; + border-color: $muted !important; + background-color: #CDD3D9; + overflow: hidden; + + &.active { + border-color: $white !important; + background-color: #ECECEC; + } + } +} diff --git a/src/views/inventory/views/badge/item/InventoryBadgeItemView.tsx b/src/views/inventory/views/badge/item/InventoryBadgeItemView.tsx new file mode 100644 index 00000000..3209271a --- /dev/null +++ b/src/views/inventory/views/badge/item/InventoryBadgeItemView.tsx @@ -0,0 +1,33 @@ +import { MouseEventType } from 'nitro-renderer'; +import { FC, MouseEvent, useCallback } from 'react'; +import { BadgeImageView } from '../../../../badge-image/BadgeImageView'; +import { useInventoryContext } from '../../../context/InventoryContext'; +import { InventoryBadgeActions } from '../../../reducers/InventoryBadgeReducer'; +import { InventoryBadgeItemViewProps } from './InventoryBadgeItemView.types'; + +export const InventoryBadgeItemView: FC = props => +{ + const { badge } = props; + const { badgeState = null, dispatchBadgeState = null } = useInventoryContext(); + const isActive = (badgeState.badge === badge); + + const onMouseEvent = useCallback((event: MouseEvent) => + { + switch(event.type) + { + case MouseEventType.MOUSE_DOWN: + dispatchBadgeState({ + type: InventoryBadgeActions.SET_BADGE, + payload: { badgeCode: badge } + }); + } + }, [ badge, dispatchBadgeState ]); + + return ( +
+
+ +
+
+ ); +} diff --git a/src/views/inventory/views/badge/item/InventoryBadgeItemView.types.ts b/src/views/inventory/views/badge/item/InventoryBadgeItemView.types.ts new file mode 100644 index 00000000..01a8727b --- /dev/null +++ b/src/views/inventory/views/badge/item/InventoryBadgeItemView.types.ts @@ -0,0 +1,4 @@ +export interface InventoryBadgeItemViewProps +{ + badge: string; +} diff --git a/src/views/inventory/views/badge/results/InventoryBadgeResultsView.scss b/src/views/inventory/views/badge/results/InventoryBadgeResultsView.scss new file mode 100644 index 00000000..37211e14 --- /dev/null +++ b/src/views/inventory/views/badge/results/InventoryBadgeResultsView.scss @@ -0,0 +1,5 @@ +.badge-item-container { + height: 144px; + max-height: 144px; + overflow-y: auto; +} diff --git a/src/views/inventory/views/badge/results/InventoryBadgeResultsView.tsx b/src/views/inventory/views/badge/results/InventoryBadgeResultsView.tsx new file mode 100644 index 00000000..da208e4e --- /dev/null +++ b/src/views/inventory/views/badge/results/InventoryBadgeResultsView.tsx @@ -0,0 +1,17 @@ +import { FC } from 'react'; +import { InventoryBadgeItemView } from '../item/InventoryBadgeItemView'; +import { InventoryBadgeResultsViewProps } from './InventoryBadgeResultsView.types'; + +export const InventoryBadgeResultsView: FC = props => +{ + const { badges = [], cols = 5 } = props; + + return ( +
+ { (badges && badges.length && badges.map((code, index) => + { + return + })) || null } +
+ ); +} diff --git a/src/views/inventory/views/badge/results/InventoryBadgeResultsView.types.ts b/src/views/inventory/views/badge/results/InventoryBadgeResultsView.types.ts new file mode 100644 index 00000000..6ee0afc2 --- /dev/null +++ b/src/views/inventory/views/badge/results/InventoryBadgeResultsView.types.ts @@ -0,0 +1,5 @@ +export interface InventoryBadgeResultsViewProps +{ + badges: string[]; + cols?: number; +}