Achievement updates

This commit is contained in:
Bill 2021-08-05 13:32:36 -04:00
parent 6721efcec5
commit 0e2e50bb77
10 changed files with 100 additions and 92 deletions

View File

@ -2,9 +2,9 @@ import { AchievementEvent, AchievementsEvent, AchievementsScoreEvent } from 'nit
import { FC, useCallback } from 'react';
import { CreateMessageHook } from '../../hooks/messages';
import { IAchievementsMessageHandlerProps } from './AchievementsMessageHandler.types';
import { AchievementCategory } from './common/AchievementCategory';
import { useAchievementsContext } from './context/AchievementsContext';
import { AchievementsActions } from './reducers/AchievementsReducer';
import { AchievementCategory } from './utils/AchievementCategory';
export const AchievementsMessageHandler: FC<IAchievementsMessageHandlerProps> = props =>
{

View File

@ -1,6 +1,10 @@
.nitro-achievements {
width: 650px;
height: 376px;
.content-area {
min-height: 376px;
height: 376px;
}
.score {
border-color: $grid-border-color !important;
@ -8,15 +12,6 @@
}
.category {
border-color: $grid-border-color !important;
background-color: $grid-bg-color;
cursor: pointer;
&.active {
border-color: $grid-active-border-color !important;
background-color: $grid-active-bg-color;
}
.category-score {
margin-top: 43.5px;
}

View File

@ -1,4 +1,4 @@
import { FC, useCallback, useEffect, useReducer, useState } from 'react';
import { FC, useCallback, useReducer, useState } from 'react';
import { AchievementsUIEvent } from '../../events/achievements';
import { useUiEvent } from '../../hooks/events';
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../layout';
@ -7,8 +7,8 @@ import { AchievementsMessageHandler } from './AchievementsMessageHandler';
import { AchievementsViewProps } from './AchievementsView.types';
import { AchievementsContextProvider } from './context/AchievementsContext';
import { AchievementsReducer, initialAchievements } from './reducers/AchievementsReducer';
import { AchievementsListView } from './views/category-list/AchievementsListView';
import { AchievementCategoryView } from './views/category/AchievementCategoryView';
import { AchievementsListView } from './views/list/AchievementsListView';
export const AchievementsView: FC<AchievementsViewProps> = props =>
{
@ -35,12 +35,6 @@ export const AchievementsView: FC<AchievementsViewProps> = props =>
useUiEvent(AchievementsUIEvent.SHOW_ACHIEVEMENTS, onAchievementsEvent);
useUiEvent(AchievementsUIEvent.HIDE_ACHIEVEMENTS, onAchievementsEvent);
useUiEvent(AchievementsUIEvent.TOGGLE_ACHIEVEMENTS, onAchievementsEvent);
useEffect(() =>
{
if(!isVisible) return;
}, [ isVisible ]);
return (
<AchievementsContextProvider value={ { achievementsState, dispatchAchievementsState } }>

View File

@ -1,5 +1,5 @@
import { Reducer } from 'react';
import { AchievementCategory } from '../utils/AchievementCategory';
import { AchievementCategory } from '../common/AchievementCategory';
export interface IAchievementsState
{

View File

@ -0,0 +1,65 @@
import { FC, useCallback, useMemo } from 'react';
import { GetConfiguration } from '../../../../api';
import { NitroCardGridItemView } from '../../../../layout/card/grid/item/NitroCardGridItemView';
import { useAchievementsContext } from '../../context/AchievementsContext';
import { AchievementsActions } from '../../reducers/AchievementsReducer';
import { AchievementCategoryListItemViewProps } from './AchievementCategoryListItemView.types';
export const AchievementCategoryListItemView: FC<AchievementCategoryListItemViewProps> = props =>
{
const { category = null, isActive = false } = props;
const { dispatchAchievementsState = null } = useAchievementsContext();
const categoryLevel = useMemo(() =>
{
let level = 0;
for(const achievement of category.achievements)
{
level = (level + (achievement.finalLevel ? achievement.level : (achievement.level - 1)));
}
return level;
}, [ category ]);
const getCategoryImage = useMemo(() =>
{
const level = categoryLevel;
const imageUrl = GetConfiguration<string>('achievements.images.url');
return imageUrl.replace('%image%', `achcategory_${ category.name }_${ ((level > 0) ? 'active' : 'inactive') }`);
}, [ category, categoryLevel ]);
const getCategoryProgress = useMemo(() =>
{
let completed = 0;
let total = 0;
for(const achievement of category.achievements)
{
if(!achievement) continue;
if(achievement.firstLevelAchieved) completed = (completed + ((achievement.finalLevel) ? achievement.level : (achievement.level - 1)));
total += achievement.scoreLimit;
}
return (completed + ' / ' + total);
}, [ category ]);
const selectCategory = useCallback((name: string) =>
{
dispatchAchievementsState({
type: AchievementsActions.SELECT_CATEGORY,
payload: {
selectedCategoryName: name
}
});
}, [ dispatchAchievementsState ]);
return (
<NitroCardGridItemView className="d-flex flex-column justify-content-center align-items-center category border border-2 rounded p-2" itemActive={ isActive } itemImage={ getCategoryImage } onClick={ event => selectCategory(category.name) }>
<div className="position-absolute category-score small">{ getCategoryProgress }</div>
</NitroCardGridItemView>
);
}

View File

@ -0,0 +1,7 @@
import { AchievementCategory } from '../../common/AchievementCategory';
export interface AchievementCategoryListItemViewProps
{
category: AchievementCategory;
isActive?: boolean;
}

View File

@ -0,0 +1,19 @@
import { FC } from 'react';
import { NitroCardGridView } from '../../../../layout/card/grid/NitroCardGridView';
import { useAchievementsContext } from '../../context/AchievementsContext';
import { AchievementCategoryListItemView } from '../category-list-item/AchievementCategoryListItemView';
export const AchievementsListView: FC<{}> = props =>
{
const { achievementsState = null, dispatchAchievementsState = null } = useAchievementsContext();;
const { categories = null, selectedCategoryName = null } = achievementsState;
return (
<NitroCardGridView columns={ 3 }>
{ categories && categories.map((category, index) =>
{
return <AchievementCategoryListItemView key={ index } category={ category } />;
}) }
</NitroCardGridView>
);
};

View File

@ -1,2 +0,0 @@
export class AchievementListViewProps
{}

View File

@ -1,70 +0,0 @@
import classNames from 'classnames';
import { FC, useCallback } from 'react';
import { GetConfiguration } from '../../../../api';
import { useAchievementsContext } from '../../context/AchievementsContext';
import { AchievementsActions } from '../../reducers/AchievementsReducer';
import { AchievementCategory } from '../../utils/AchievementCategory';
import { AchievementListViewProps } from './AchievementListView.types';
export const AchievementsListView: FC<AchievementListViewProps> = props =>
{
const achievementsContext = useAchievementsContext();
const { achievementsState = null, dispatchAchievementsState = null } = achievementsContext;
const { categories = null, selectedCategoryName = null } = achievementsState;
const getCategoryImage = useCallback((category: AchievementCategory) =>
{
let level = 0;
for(const achievement of category.achievements)
{
level = (level + ((achievement.finalLevel) ? achievement.level : (achievement.level - 1)));
}
const isActive = ((level > 0) ? 'active' : 'inactive');
return GetConfiguration('achievements.images.url', GetConfiguration('achievements.images.url') + `quests/achcategory_${category.name}_${isActive}.png`).replace('%image%',`achcategory_${category.name}_${isActive}`);
}, []);
const getCategoryProgress = useCallback((category: AchievementCategory) =>
{
let completed = 0;
let total = 0;
for(const achievement of category.achievements)
{
if(!achievement) continue;
if(achievement.finalLevel) completed = completed + 1 + achievement.level;
total = (total + achievement.scoreLimit);
}
return (completed + ' / ' + total);
}, []);
const selectCategory = useCallback((name: string) =>
{
dispatchAchievementsState({
type: AchievementsActions.SELECT_CATEGORY,
payload: {
selectedCategoryName: name
}
});
}, [ dispatchAchievementsState ]);
return (
<div className="row row-cols-3">
{ categories && categories.map((category, index) =>
{
return <div key={ index } className="col mb-3">
<div className={'category border border-2 rounded d-flex flex-column justify-content-center align-items-center p-2' + classNames({' active': selectedCategoryName === category.name})} onClick={() => selectCategory(category.name)}>
<img alt="" src={getCategoryImage(category)} />
<div className="position-absolute category-score small">{ getCategoryProgress(category) }</div>
</div>
</div>
}) }
</div>
);
};