Update achievements

This commit is contained in:
Bill 2022-10-24 02:26:46 -04:00
parent 1ef9190fab
commit 99e98048e0
11 changed files with 65 additions and 68 deletions

View File

@ -1,5 +1,5 @@
import { ILinkEventTracker } from '@nitrots/nitro-renderer';
import { FC, useEffect, useMemo, useState } from 'react';
import { FC, useEffect, useState } from 'react';
import { AchievementUtilities, AddEventLinkTracker, LocalizeText, RemoveLinkEventTracker } from '../../api';
import { Base, Column, LayoutImage, LayoutProgressBar, NitroCardContentView, NitroCardHeaderView, NitroCardSubHeaderView, NitroCardView, Text } from '../../common';
import { useAchievements } from '../../hooks';
@ -9,14 +9,7 @@ import { AchievementsCategoryListView } from './views/category-list/Achievements
export const AchievementsView: FC<{}> = props =>
{
const [ isVisible, setIsVisible ] = useState(false);
const { achievementCategories = [], selectedCategoryCode = null, setSelectedCategoryCode = null, selectedAchievementId = -1, setSelectedAchievementId = null, achievementScore = 0, getProgress = 0, getMaxProgress = 0, setAchievementSeen = null } = useAchievements();
const selectedCategory = useMemo(() =>
{
if(selectedCategoryCode === null) return null;
return achievementCategories.find(category => (category.code === selectedCategoryCode));
}, [ achievementCategories, selectedCategoryCode ]);
const { achievementCategories = [], selectedCategoryCode = null, setSelectedCategoryCode = null, achievementScore = 0, getProgress = 0, getMaxProgress = 0, selectedCategory = null } = useAchievements();
useEffect(() =>
{
@ -72,7 +65,7 @@ export const AchievementsView: FC<{}> = props =>
</Column>
</> }
{ selectedCategory &&
<AchievementCategoryView category={ selectedCategory } selectedAchievementId={ selectedAchievementId } setSelectedAchievementId={ setSelectedAchievementId } setAchievementSeen={ setAchievementSeen } /> }
<AchievementCategoryView category={ selectedCategory } /> }
</NitroCardContentView>
</NitroCardView>
);

View File

@ -1,48 +1,35 @@
import { Dispatch, FC, SetStateAction, useEffect, useMemo } from 'react';
import { FC, useEffect } from 'react';
import { AchievementCategory } from '../../../api';
import { Column } from '../../../common';
import { AchievementListView } from './achievement-list/AchievementListView';
import { useAchievements } from '../../../hooks';
import { AchievementListView } from './achievement-list';
import { AchievementDetailsView } from './AchievementDetailsView';
interface AchievementCategoryViewProps
{
category: AchievementCategory;
selectedAchievementId: number;
setSelectedAchievementId: Dispatch<SetStateAction<number>>;
setAchievementSeen: (code: string, achievementId: number) => void;
}
export const AchievementCategoryView: FC<AchievementCategoryViewProps> = props =>
{
const { category = null, selectedAchievementId = -1, setSelectedAchievementId = null, setAchievementSeen = null } = props;
const selectedAchievement = useMemo(() =>
{
if(selectedAchievementId === -1) return null;
return category.achievements.find(achievement => (achievement.achievementId === selectedAchievementId));
}, [ category, selectedAchievementId ]);
const { category = null } = props;
const { selectedAchievement = null, setSelectedAchievementId = null } = useAchievements();
useEffect(() =>
{
if(!category) return;
if(!selectedAchievement)
{
if(category.achievements.length) setSelectedAchievementId(category.achievements[0].achievementId);
setSelectedAchievementId(category?.achievements?.[0]?.achievementId);
}
}, [ selectedAchievement, category, setSelectedAchievementId ]);
useEffect(() =>
{
if(!selectedAchievement) return;
setAchievementSeen(category.code, selectedAchievement.achievementId);
}, [ selectedAchievement, category, setAchievementSeen ]);
}, [ category, selectedAchievement, setSelectedAchievementId ]);
if(!category) return null;
return (
<Column fullHeight justifyContent="between">
<AchievementListView achievements={ category.achievements } selectedAchievementId={ selectedAchievementId } setSelectedAchievementId={ setSelectedAchievementId } />
<AchievementListView achievements={ category.achievements } />
{ !!selectedAchievement &&
<AchievementDetailsView achievement={ selectedAchievement } /> }
</Column>

View File

@ -1,5 +1,5 @@
import { AchievementData } from '@nitrots/nitro-renderer';
import { FC, PropsWithChildren } from 'react';
import { FC } from 'react';
import { AchievementUtilities, LocalizeBadgeDescription, LocalizeBadgeName, LocalizeText } from '../../../api';
import { Column, Flex, LayoutCurrencyIcon, LayoutProgressBar, Text } from '../../../common';
import { AchievementBadgeView } from './AchievementBadgeView';
@ -9,14 +9,14 @@ interface AchievementDetailsViewProps
achievement: AchievementData;
}
export const AchievementDetailsView: FC<PropsWithChildren<AchievementDetailsViewProps>> = props =>
export const AchievementDetailsView: FC<AchievementDetailsViewProps> = props =>
{
const { achievement = null, children = null, ...rest } = props;
const { achievement = null } = props;
if(!achievement) return null;
return (
<Flex shrink className="bg-muted rounded p-2 text-black" gap={ 2 } overflow="hidden" { ...rest }>
<Flex shrink className="bg-muted rounded p-2 text-black" gap={ 2 } overflow="hidden">
<Column center gap={ 1 }>
<AchievementBadgeView className="nitro-achievements-badge-image" achievement={ achievement } scale={ 2 } />
<Text fontWeight="bold">
@ -48,7 +48,6 @@ export const AchievementDetailsView: FC<PropsWithChildren<AchievementDetailsView
<LayoutProgressBar text={ LocalizeText('achievements.details.progress', [ 'progress', 'limit' ], [ (achievement.currentPoints + achievement.scoreAtStartOfLevel).toString(), (achievement.scoreLimit + achievement.scoreAtStartOfLevel).toString() ]) } progress={ (achievement.currentPoints + achievement.scoreAtStartOfLevel) } maxProgress={ (achievement.scoreLimit + achievement.scoreAtStartOfLevel) } /> }
</Column> }
</Column>
{ children }
</Flex>
)
}

View File

@ -1,25 +1,24 @@
import { AchievementData } from '@nitrots/nitro-renderer';
import { Dispatch, FC, PropsWithChildren, SetStateAction } from 'react';
import { FC } from 'react';
import { LayoutGridItem } from '../../../../common';
import { useAchievements } from '../../../../hooks';
import { AchievementBadgeView } from '../AchievementBadgeView';
interface AchievementListItemViewProps
{
achievement: AchievementData;
selectedAchievementId: number;
setSelectedAchievementId: Dispatch<SetStateAction<number>>;
}
export const AchievementListItemView: FC<PropsWithChildren<AchievementListItemViewProps>> = props =>
export const AchievementListItemView: FC<AchievementListItemViewProps> = props =>
{
const { achievement = null, selectedAchievementId = -1, setSelectedAchievementId = null, children = null, ...rest } = props;
const { achievement = null } = props;
const { selectedAchievement = null, setSelectedAchievementId = null } = useAchievements();
if(!achievement) return null;
return (
<LayoutGridItem itemActive={ (selectedAchievementId === achievement.achievementId) } itemUnseen={ (achievement.unseen > 0) } onClick={ event => setSelectedAchievementId(achievement.achievementId) } { ...rest }>
<LayoutGridItem itemActive={ (selectedAchievement === achievement) } itemUnseen={ (achievement.unseen > 0) } onClick={ event => setSelectedAchievementId(achievement.achievementId) }>
<AchievementBadgeView achievement={ achievement } />
{ children }
</LayoutGridItem>
);
}

View File

@ -1,23 +1,20 @@
import { AchievementData } from '@nitrots/nitro-renderer';
import { Dispatch, FC, PropsWithChildren, SetStateAction } from 'react';
import { FC } from 'react';
import { AutoGrid } from '../../../../common';
import { AchievementListItemView } from './AchievementListItemView';
interface AchievementListViewProps
{
achievements: AchievementData[];
selectedAchievementId: number;
setSelectedAchievementId: Dispatch<SetStateAction<number>>;
}
export const AchievementListView: FC<PropsWithChildren<AchievementListViewProps>> = props =>
export const AchievementListView: FC<AchievementListViewProps> = props =>
{
const { achievements = null, selectedAchievementId = -1, setSelectedAchievementId = null, children = null, ...rest } = props;
const { achievements = null } = props;
return (
<AutoGrid columnCount={ 6 } columnMinWidth={ 50 } columnMinHeight={ 50 } { ...rest }>
{ achievements && (achievements.length > 0) && achievements.map((achievement, index) => <AchievementListItemView key={ index } achievement={ achievement } selectedAchievementId={ selectedAchievementId } setSelectedAchievementId={ setSelectedAchievementId } />) }
{ children }
<AutoGrid columnCount={ 6 } columnMinWidth={ 50 } columnMinHeight={ 50 }>
{ achievements && (achievements.length > 0) && achievements.map((achievement, index) => <AchievementListItemView key={ index } achievement={ achievement } />) }
</AutoGrid>
);
}

View File

@ -0,0 +1,2 @@
export * from './AchievementListItemView';
export * from './AchievementListView';

View File

@ -1,4 +1,4 @@
import { Dispatch, FC, PropsWithChildren, SetStateAction } from 'react';
import { Dispatch, FC, SetStateAction } from 'react';
import { AchievementUtilities, IAchievementCategory, LocalizeText } from '../../../../api';
import { LayoutBackgroundImage, LayoutGridItem, Text } from '../../../../common';
@ -9,9 +9,9 @@ interface AchievementCategoryListItemViewProps
setSelectedCategoryCode: Dispatch<SetStateAction<string>>;
}
export const AchievementsCategoryListItemView: FC<PropsWithChildren<AchievementCategoryListItemViewProps>> = props =>
export const AchievementsCategoryListItemView: FC<AchievementCategoryListItemViewProps> = props =>
{
const { category = null, selectedCategoryCode = null, setSelectedCategoryCode = null, children = null, ...rest } = props;
const { category = null, selectedCategoryCode = null, setSelectedCategoryCode = null } = props;
if(!category) return null;
@ -21,12 +21,11 @@ export const AchievementsCategoryListItemView: FC<PropsWithChildren<AchievementC
const getTotalUnseen = AchievementUtilities.getAchievementCategoryTotalUnseen(category);
return (
<LayoutGridItem itemActive={ (selectedCategoryCode === category.code) } itemCount={ getTotalUnseen } itemCountMinimum={ 0 } gap={ 1 } onClick={ event => setSelectedCategoryCode(category.code) } { ...rest }>
<LayoutGridItem itemActive={ (selectedCategoryCode === category.code) } itemCount={ getTotalUnseen } itemCountMinimum={ 0 } gap={ 1 } onClick={ event => setSelectedCategoryCode(category.code) }>
<Text fullWidth center small className="pt-1">{ LocalizeText(`quests.${ category.code }.name`) }</Text>
<LayoutBackgroundImage position="relative" imageUrl={ getCategoryImage }>
<Text fullWidth center position="absolute" variant="white" style={ { fontSize: 12, bottom: 9 } }>{ progress } / { maxProgress }</Text>
</LayoutBackgroundImage>
{ children }
</LayoutGridItem>
);
}

View File

@ -1,4 +1,4 @@
import { Dispatch, FC, PropsWithChildren, SetStateAction } from 'react';
import { Dispatch, FC, SetStateAction } from 'react';
import { IAchievementCategory } from '../../../../api';
import { AutoGrid } from '../../../../common';
import { AchievementsCategoryListItemView } from './AchievementsCategoryListItemView';
@ -10,14 +10,13 @@ interface AchievementsCategoryListViewProps
setSelectedCategoryCode: Dispatch<SetStateAction<string>>;
}
export const AchievementsCategoryListView: FC<PropsWithChildren<AchievementsCategoryListViewProps>> = props =>
export const AchievementsCategoryListView: FC<AchievementsCategoryListViewProps> = props =>
{
const { categories = null, selectedCategoryCode = null, setSelectedCategoryCode = null, children = null, ...rest } = props;
const { categories = null, selectedCategoryCode = null, setSelectedCategoryCode = null } = props;
return (
<AutoGrid columnCount={ 3 } columnMinWidth={ 90 } columnMinHeight={ 100 } { ...rest }>
<AutoGrid columnCount={ 3 } columnMinWidth={ 90 } columnMinHeight={ 100 }>
{ categories && (categories.length > 0) && categories.map((category, index) => <AchievementsCategoryListItemView key={ index } category={ category } selectedCategoryCode={ selectedCategoryCode } setSelectedCategoryCode={ setSelectedCategoryCode } /> ) }
{ children }
</AutoGrid>
);
};

View File

@ -0,0 +1,2 @@
export * from './AchievementsCategoryListItemView';
export * from './AchievementsCategoryListView';

View File

@ -0,0 +1,5 @@
export * from './achievement-list';
export * from './AchievementBadgeView';
export * from './AchievementCategoryView';
export * from './AchievementDetailsView';
export * from './category-list';

View File

@ -1,5 +1,6 @@
import { AchievementData, AchievementEvent, AchievementsEvent, AchievementsScoreEvent, RequestAchievementsMessageComposer } from '@nitrots/nitro-renderer';
import { useEffect, useMemo, useState } from 'react';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { useBetween } from 'use-between';
import { AchievementCategory, AchievementUtilities, CloneObject, SendMessageComposer } from '../../api';
import { useMessageEvent } from '../events';
@ -43,7 +44,21 @@ const useAchievementsState = () =>
return ~~((((getProgress - 0) * (100 - 0)) / (getMaxProgress - 0)) + 0);
}, [ getProgress, getMaxProgress ]);
const setAchievementSeen = (categoryCode: string, achievementId: number) =>
const selectedCategory = useMemo(() =>
{
if(selectedCategoryCode === null) return null;
return achievementCategories.find(category => (category.code === selectedCategoryCode));
}, [ achievementCategories, selectedCategoryCode ]);
const selectedAchievement = useMemo(() =>
{
if((selectedAchievementId === -1) || !selectedCategory) return null;
return selectedCategory.achievements.find(achievement => (achievement.achievementId === selectedAchievementId));
}, [ selectedCategory, selectedAchievementId ]);
const setAchievementSeen = useCallback((categoryCode: string, achievementId: number) =>
{
setAchievementCategories(prevValue =>
{
@ -63,7 +78,7 @@ const useAchievementsState = () =>
return newValue;
});
}
}, []);
useMessageEvent<AchievementEvent>(AchievementEvent, event =>
{
@ -157,7 +172,7 @@ const useAchievementsState = () =>
setNeedsUpdate(false);
}, [ needsUpdate ]);
return { achievementCategories, selectedCategoryCode, setSelectedCategoryCode, selectedAchievementId, setSelectedAchievementId, achievementScore, getTotalUnseen, getProgress, getMaxProgress, scaledProgressPercent, setAchievementSeen };
return { achievementCategories, selectedCategoryCode, setSelectedCategoryCode, selectedAchievementId, setSelectedAchievementId, achievementScore, getTotalUnseen, getProgress, getMaxProgress, scaledProgressPercent, selectedCategory, selectedAchievement, setAchievementSeen };
}
export const useAchievements = useAchievementsState;
export const useAchievements = () => useBetween(useAchievementsState);