Update achievements

This commit is contained in:
Bill 2022-03-23 03:05:44 -04:00
parent c8ca5d2b82
commit d1a7badeba
20 changed files with 182 additions and 189 deletions

View File

@ -19,7 +19,7 @@ $grid-active-border-color: $white;
$toolbar-height: 55px; $toolbar-height: 55px;
$achievement-width: 375px; $achievement-width: 375px;
$achievement-height: 425px; $achievement-height: 415px;
$avatar-editor-width: 620px; $avatar-editor-width: 620px;
$avatar-editor-height: 374px; $avatar-editor-height: 374px;

View File

@ -0,0 +1,13 @@
import { AchievementData } from '@nitrots/nitro-renderer';
import { GetLocalization } from '..';
export const GetAchievementBadgeCode = (achievement: AchievementData) =>
{
if(!achievement) return null;
let badgeId = achievement.badgeId;
if(!achievement.finalLevel) badgeId = GetLocalization().getPreviousLevelBadgeId(badgeId);
return badgeId;
}

View File

@ -0,0 +1,10 @@
import { AchievementData } from '@nitrots/nitro-renderer';
export const GetAchievementHasStarted = (achievement: AchievementData) =>
{
if(!achievement) return false;
if(achievement.finalLevel || ((achievement.level - 1) > 0)) return true;
return false;
}

View File

@ -0,0 +1,15 @@
import { AchievementData } from '@nitrots/nitro-renderer';
import { GetConfiguration } from '..';
export const GetAchievementIsIgnored = (achievement: AchievementData) =>
{
if(!achievement) return false;
const ignored = GetConfiguration<string[]>('achievements.unseen.ignored');
const value = achievement.badgeId.replace(/[0-9]/g, '');
const index = ignored.indexOf(value);
if(index >= 0) return true;
return false;
}

View File

@ -0,0 +1,5 @@
export * from './AchievementCategory';
export * from './GetAchievementBadgeCode';
export * from './GetAchievementHasStarted';
export * from './GetAchievementIsIgnored';
export * from './GetAchievementLevel';

View File

@ -1,3 +1,4 @@
export * from './achievements';
export * from './common'; export * from './common';
export * from './core'; export * from './core';
export * from './friends'; export * from './friends';

View File

@ -1,13 +1,11 @@
import { AchievementData, AchievementEvent, AchievementsEvent, AchievementsScoreEvent, RequestAchievementsMessageComposer } from '@nitrots/nitro-renderer'; import { AchievementData, AchievementEvent, AchievementsEvent, AchievementsScoreEvent, ILinkEventTracker, RequestAchievementsMessageComposer } from '@nitrots/nitro-renderer';
import { FC, useCallback, useEffect, useMemo, useState } from 'react'; import { FC, useCallback, useEffect, useMemo, useState } from 'react';
import { GetConfiguration, LocalizeText, SendMessageComposer } from '../../api'; import { AchievementCategory, AddEventLinkTracker, GetAchievementIsIgnored, LocalizeText, RemoveLinkEventTracker, SendMessageComposer } from '../../api';
import { Base, Column, Flex, NitroCardContentView, NitroCardHeaderView, NitroCardSubHeaderView, NitroCardView, Text } from '../../common'; import { Base, Column, LayoutProgressBar, NitroCardContentView, NitroCardHeaderView, NitroCardSubHeaderView, NitroCardView, Text } from '../../common';
import { AchievementsUIEvent, AchievementsUIUnseenCountEvent } from '../../events'; import { AchievementsUIUnseenCountEvent } from '../../events';
import { BatchUpdates, DispatchUiEvent, UseMessageEventHook, UseUiEvent } from '../../hooks'; import { BatchUpdates, DispatchUiEvent, UseMessageEventHook } from '../../hooks';
import { AchievementCategory } from './common/AchievementCategory'; import { AchievementCategoryView } from './views/AchievementCategoryView';
import { AchievementUtilities } from './common/AchievementUtilities';
import { AchievementsCategoryListView } from './views/category-list/AchievementsCategoryListView'; import { AchievementsCategoryListView } from './views/category-list/AchievementsCategoryListView';
import { AchievementCategoryView } from './views/category/AchievementCategoryView';
export const AchievementsView: FC<{}> = props => export const AchievementsView: FC<{}> = props =>
{ {
@ -17,72 +15,56 @@ export const AchievementsView: FC<{}> = props =>
const [ selectedCategoryCode, setSelectedCategoryCode ] = useState<string>(null); const [ selectedCategoryCode, setSelectedCategoryCode ] = useState<string>(null);
const [ achievementScore, setAchievementScore ] = useState(0); const [ achievementScore, setAchievementScore ] = useState(0);
const onAchievementsUIEvent = useCallback((event: AchievementsUIEvent) =>
{
switch(event.type)
{
case AchievementsUIEvent.SHOW_ACHIEVEMENTS:
setIsVisible(true);
return;
case AchievementsUIEvent.HIDE_ACHIEVEMENTS:
setIsVisible(false);
return;
case AchievementsUIEvent.TOGGLE_ACHIEVEMENTS:
setIsVisible(value => !value);
return;
}
}, []);
UseUiEvent(AchievementsUIEvent.SHOW_ACHIEVEMENTS, onAchievementsUIEvent);
UseUiEvent(AchievementsUIEvent.HIDE_ACHIEVEMENTS, onAchievementsUIEvent);
UseUiEvent(AchievementsUIEvent.TOGGLE_ACHIEVEMENTS, onAchievementsUIEvent);
const onAchievementEvent = useCallback((event: AchievementEvent) => const onAchievementEvent = useCallback((event: AchievementEvent) =>
{ {
const parser = event.getParser(); const parser = event.getParser();
const achievement = parser.achievement; const achievement = parser.achievement;
const newCategories = [ ...achievementCategories ];
const categoryName = achievement.category; const categoryName = achievement.category;
const categoryIndex = newCategories.findIndex(existing => (existing.code === categoryName));
if(categoryIndex === -1) setAchievementCategories(prevValue =>
{
const category = new AchievementCategory(categoryName);
category.achievements.push(achievement);
newCategories.push(category);
}
else
{
const category = newCategories[categoryIndex];
const newAchievements = [ ...category.achievements ];
const achievementIndex = newAchievements.findIndex(existing => (existing.achievementId === achievement.achievementId));
let previousAchievement: AchievementData = null;
if(achievementIndex === -1)
{ {
newAchievements.push(achievement); const newValue = [ ...prevValue ];
} const categoryIndex = newValue.findIndex(existing => (existing.code === categoryName));
else
{
previousAchievement = newAchievements[achievementIndex];
newAchievements[achievementIndex] = achievement; if(categoryIndex === -1)
} {
const category = new AchievementCategory(categoryName);
if(!AchievementUtilities.isIgnoredAchievement(achievement)) category.achievements.push(achievement);
{
achievement.unseen++;
if(previousAchievement) achievement.unseen += previousAchievement.unseen; newValue.push(category);
} }
else
{
const category = newValue[categoryIndex];
const newAchievements = [ ...category.achievements ];
const achievementIndex = newAchievements.findIndex(existing => (existing.achievementId === achievement.achievementId));
let previousAchievement: AchievementData = null;
category.achievements = newAchievements; if(achievementIndex === -1)
} {
newAchievements.push(achievement);
}
else
{
previousAchievement = newAchievements[achievementIndex];
setAchievementCategories(newCategories); newAchievements[achievementIndex] = achievement;
}, [ achievementCategories ]); }
if(!GetAchievementIsIgnored(achievement))
{
achievement.unseen++;
if(previousAchievement) achievement.unseen += previousAchievement.unseen;
}
category.achievements = newAchievements;
}
return newValue;
});
}, []);
UseMessageEventHook(AchievementEvent, onAchievementEvent); UseMessageEventHook(AchievementEvent, onAchievementEvent);
@ -95,6 +77,7 @@ export const AchievementsView: FC<{}> = props =>
for(const achievement of parser.achievements) for(const achievement of parser.achievements)
{ {
const categoryName = achievement.category; const categoryName = achievement.category;
let existing = categories.find(category => (category.code === categoryName)); let existing = categories.find(category => (category.code === categoryName));
if(!existing) if(!existing)
@ -167,33 +150,59 @@ export const AchievementsView: FC<{}> = props =>
return achievementCategories.find(existing => (existing.code === selectedCategoryCode)); return achievementCategories.find(existing => (existing.code === selectedCategoryCode));
}, [ achievementCategories, selectedCategoryCode ]); }, [ achievementCategories, selectedCategoryCode ]);
const getCategoryIcon = useMemo(() =>
{
if(!getSelectedCategory) return null;
const imageUrl = GetConfiguration<string>('achievements.images.url');
return imageUrl.replace('%image%', `achicon_${ getSelectedCategory.code }`);
}, [ getSelectedCategory ]);
const setAchievementSeen = useCallback((code: string, achievementId: number) => const setAchievementSeen = useCallback((code: string, achievementId: number) =>
{ {
const newCategories = [ ...achievementCategories ]; setAchievementCategories(prevValue =>
for(const category of newCategories)
{
if(category.code !== code) continue;
for(const achievement of category.achievements)
{ {
if(achievement.achievementId !== achievementId) continue; const newValue = [ ...prevValue ];
achievement.unseen = 0; for(const category of newValue)
} {
if(category.code !== code) continue;
for(const achievement of category.achievements)
{
if(achievement.achievementId !== achievementId) continue;
achievement.unseen = 0;
}
}
return newValue;
});
}, []);
const linkReceived = useCallback((url: string) =>
{
const parts = url.split('/');
if(parts.length < 2) return;
switch(parts[1])
{
case 'show':
setIsVisible(true);
return;
case 'hide':
setIsVisible(false);
return;
case 'toggle':
setIsVisible(prevValue => !prevValue);
return;
} }
}, []);
setAchievementCategories(newCategories); useEffect(() =>
}, [ achievementCategories ]); {
const linkTracker: ILinkEventTracker = {
linkReceived,
eventUrlPrefix: 'achievements/'
};
AddEventLinkTracker(linkTracker);
return () => RemoveLinkEventTracker(linkTracker);
}, [ linkReceived ]);
useEffect(() => useEffect(() =>
{ {
@ -220,15 +229,12 @@ export const AchievementsView: FC<{}> = props =>
<Text>{ LocalizeText('achievements.details.categoryprogress', [ 'progress', 'limit' ], [ getSelectedCategory.getProgress().toString(), getSelectedCategory.getMaxProgress().toString() ]) }</Text> <Text>{ LocalizeText('achievements.details.categoryprogress', [ 'progress', 'limit' ], [ getSelectedCategory.getProgress().toString(), getSelectedCategory.getMaxProgress().toString() ]) }</Text>
</Column> </Column>
</NitroCardSubHeaderView> } </NitroCardSubHeaderView> }
<NitroCardContentView> <NitroCardContentView gap={ 1 }>
{ !getSelectedCategory && { !getSelectedCategory &&
<> <>
<AchievementsCategoryListView categories={ achievementCategories } selectedCategoryCode={ selectedCategoryCode } setSelectedCategoryCode={ setSelectedCategoryCode } /> <AchievementsCategoryListView categories={ achievementCategories } selectedCategoryCode={ selectedCategoryCode } setSelectedCategoryCode={ setSelectedCategoryCode } />
<Column grow justifyContent="end"> <Column grow justifyContent="end">
<Base className="progress" position="relative"> <LayoutProgressBar text={ LocalizeText('achievements.categories.totalprogress', [ 'progress', 'limit' ], [ getProgress.toString(), getMaxProgress.toString() ]) } progress={ getProgress } maxProgress={ getMaxProgress } />
<Flex fit center position="absolute" className="text-black">{ LocalizeText('achievements.categories.totalprogress', [ 'progress', 'limit' ], [ getProgress.toString(), getMaxProgress.toString() ]) }</Flex>
<Base className="progress-bar bg-success" style={ { width: (scaledProgressPercent + '%') }} />
</Base>
<Text className="bg-muted rounded p-1" center>{ LocalizeText('achievements.categories.score', [ 'score' ], [ achievementScore.toString() ]) }</Text> <Text className="bg-muted rounded p-1" center>{ LocalizeText('achievements.categories.score', [ 'score' ], [ achievementScore.toString() ]) }</Text>
</Column> </Column>
</> } </> }

View File

@ -1,38 +0,0 @@
import { AchievementData } from '@nitrots/nitro-renderer';
import { GetConfiguration, GetLocalization } from '../../../api';
export class AchievementUtilities
{
public static hasStarted(achievement: AchievementData): boolean
{
if(!achievement) return false;
if(achievement.finalLevel || ((achievement.level - 1) > 0)) return true;
return false;
}
public static getBadgeCode(achievement: AchievementData): string
{
if(!achievement) return null;
let badgeId = achievement.badgeId;
if(!achievement.finalLevel) badgeId = GetLocalization().getPreviousLevelBadgeId(badgeId);
return badgeId;
}
public static isIgnoredAchievement(achievement: AchievementData): boolean
{
if(!achievement) return false;
const ignored = GetConfiguration<string[]>('achievements.unseen.ignored');
const value = achievement.badgeId.replace(/[0-9]/g, '');
const index = ignored.indexOf(value);
if(index >= 0) return true;
return false;
}
}

View File

@ -1,8 +0,0 @@
import { AchievementData } from '@nitrots/nitro-renderer';
export const GetScaledProgressPercent = (achievement: AchievementData) =>
{
if(!achievement) return 0;
return ~~(((((achievement.currentPoints + achievement.scoreAtStartOfLevel) - 0) * (100 - 0)) / ((achievement.scoreLimit + achievement.scoreAtStartOfLevel) - 0)) + 0);
}

View File

@ -0,0 +1,19 @@
import { AchievementData } from '@nitrots/nitro-renderer';
import { FC } from 'react';
import { GetAchievementBadgeCode, GetAchievementHasStarted } from '../../../api';
import { BaseProps, LayoutBadgeImageView } from '../../../common';
interface AchievementBadgeViewProps extends BaseProps<HTMLDivElement>
{
achievement: AchievementData;
scale?: number;
}
export const AchievementBadgeView: FC<AchievementBadgeViewProps> = props =>
{
const { achievement = null, scale = 1, ...rest } = props;
if(!achievement) return null;
return <LayoutBadgeImageView badgeCode={ GetAchievementBadgeCode(achievement) } isGrayscale={ !GetAchievementHasStarted(achievement) } scale={ scale } { ...rest } />;
}

View File

@ -1,10 +1,10 @@
import { FC, useEffect, useMemo, useState } from 'react'; import { FC, useEffect, useMemo, useState } from 'react';
import { Column } from '../../../../common/Column'; import { AchievementCategory } from '../../../api';
import { AchievementCategory } from '../../common/AchievementCategory'; import { Column } from '../../../common';
import { AchievementDetailsView } from '../achievement-details/AchievementDetailsView'; import { AchievementListView } from './achievement-list/AchievementListView';
import { AchievementListView } from '../achievement-list/AchievementListView'; import { AchievementDetailsView } from './AchievementDetailsView';
export class AchievementCategoryViewProps interface AchievementCategoryViewProps
{ {
category: AchievementCategory; category: AchievementCategory;
setAchievementSeen: (code: string, achievementId: number) => void; setAchievementSeen: (code: string, achievementId: number) => void;

View File

@ -1,13 +1,11 @@
import { AchievementData } from '@nitrots/nitro-renderer'; import { AchievementData } from '@nitrots/nitro-renderer';
import { FC } from 'react'; import { FC } from 'react';
import { LocalizeBadgeDescription, LocalizeBadgeName, LocalizeText } from '../../../../api'; import { GetAchievementBadgeCode, LocalizeBadgeDescription, LocalizeBadgeName, LocalizeText } from '../../../api';
import { Base, Column, Flex, LayoutCurrencyIcon, Text } from '../../../../common'; import { GetAchievementLevel } from '../../../api/achievements/GetAchievementLevel';
import { AchievementUtilities } from '../../common/AchievementUtilities'; import { Column, Flex, LayoutCurrencyIcon, LayoutProgressBar, Text } from '../../../common';
import { GetAchievementLevel } from '../../common/GetAchievementLevel'; import { AchievementBadgeView } from './AchievementBadgeView';
import { GetScaledProgressPercent } from '../../common/GetScaledProgressPercent';
import { AchievementBadgeView } from '../achievement-badge/AchievementBadgeView';
export interface AchievementDetailsViewProps interface AchievementDetailsViewProps
{ {
achievement: AchievementData; achievement: AchievementData;
} }
@ -19,7 +17,6 @@ export const AchievementDetailsView: FC<AchievementDetailsViewProps> = props =>
if(!achievement) return null; if(!achievement) return null;
const achievementLevel = GetAchievementLevel(achievement); const achievementLevel = GetAchievementLevel(achievement);
const scaledProgressPercent = GetScaledProgressPercent(achievement);
return ( return (
<Flex shrink className="bg-muted rounded p-2 text-black" gap={ 2 } overflow="hidden"> <Flex shrink className="bg-muted rounded p-2 text-black" gap={ 2 } overflow="hidden">
@ -32,10 +29,10 @@ export const AchievementDetailsView: FC<AchievementDetailsViewProps> = props =>
<Column fullWidth justifyContent="center" overflow="hidden"> <Column fullWidth justifyContent="center" overflow="hidden">
<Column gap={ 1 }> <Column gap={ 1 }>
<Text fontWeight="bold" truncate> <Text fontWeight="bold" truncate>
{ LocalizeBadgeName(AchievementUtilities.getBadgeCode(achievement)) } { LocalizeBadgeName(GetAchievementBadgeCode(achievement)) }
</Text> </Text>
<Text truncate> <Text textBreak>
{ LocalizeBadgeDescription(AchievementUtilities.getBadgeCode(achievement)) } { LocalizeBadgeDescription(GetAchievementBadgeCode(achievement)) }
</Text> </Text>
</Column> </Column>
{ ((achievement.levelRewardPoints > 0) || (achievement.scoreLimit > 0)) && { ((achievement.levelRewardPoints > 0) || (achievement.scoreLimit > 0)) &&
@ -51,10 +48,7 @@ export const AchievementDetailsView: FC<AchievementDetailsViewProps> = props =>
</Flex> </Flex>
</Flex> } </Flex> }
{ (achievement.scoreLimit > 0) && { (achievement.scoreLimit > 0) &&
<Base className="progress" position="relative"> <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) } /> }
<Flex fit center position="absolute" className="text-black"> { LocalizeText('achievements.details.progress', [ 'progress', 'limit' ], [ (achievement.currentPoints + achievement.scoreAtStartOfLevel).toString(), (achievement.scoreLimit + achievement.scoreAtStartOfLevel).toString() ]) }</Flex>
<Base className="progress-bar" style={ { width: (scaledProgressPercent + '%') }} />
</Base> }
</Column> } </Column> }
</Column> </Column>
</Flex> </Flex>

View File

@ -1,21 +0,0 @@
import { AchievementData } from '@nitrots/nitro-renderer';
import { FC } from 'react';
import { BaseProps, LayoutBadgeImageView } from '../../../../common';
import { AchievementUtilities } from '../../common/AchievementUtilities';
export interface AchievementBadgeViewProps extends BaseProps<HTMLDivElement>
{
achievement: AchievementData;
scale?: number;
}
export const AchievementBadgeView: FC<AchievementBadgeViewProps> = props =>
{
const { achievement = null, scale = 1, ...rest } = props;
if(!achievement) return null;
return (
<LayoutBadgeImageView badgeCode={ AchievementUtilities.getBadgeCode(achievement) } isGrayscale={ !AchievementUtilities.hasStarted(achievement) } scale={ scale } { ...rest } />
);
}

View File

@ -1,9 +1,9 @@
import { AchievementData } from '@nitrots/nitro-renderer'; import { AchievementData } from '@nitrots/nitro-renderer';
import { FC } from 'react'; import { FC } from 'react';
import { LayoutGridItem, LayoutGridItemProps } from '../../../../common/layout/LayoutGridItem'; import { LayoutGridItem, LayoutGridItemProps } from '../../../../common';
import { AchievementBadgeView } from '../achievement-badge/AchievementBadgeView'; import { AchievementBadgeView } from '../AchievementBadgeView';
export interface AchievementListItemViewProps extends LayoutGridItemProps interface AchievementListItemViewProps extends LayoutGridItemProps
{ {
achievement: AchievementData; achievement: AchievementData;
} }

View File

@ -1,6 +1,6 @@
import { AchievementData } from '@nitrots/nitro-renderer'; import { AchievementData } from '@nitrots/nitro-renderer';
import { Dispatch, FC, SetStateAction } from 'react'; import { Dispatch, FC, SetStateAction } from 'react';
import { AutoGrid } from '../../../../common/AutoGrid'; import { AutoGrid } from '../../../../common';
import { AchievementListItemView } from './AchievementListItemView'; import { AchievementListItemView } from './AchievementListItemView';
export interface AchievementListViewProps export interface AchievementListViewProps

View File

@ -1,9 +1,6 @@
import { FC, useCallback, useMemo } from 'react'; import { FC, useCallback, useMemo } from 'react';
import { GetConfiguration, LocalizeText } from '../../../../api'; import { AchievementCategory, GetConfiguration, LocalizeText } from '../../../../api';
import { LayoutGridItem, LayoutGridItemProps } from '../../../../common/layout/LayoutGridItem'; import { LayoutGridItem, LayoutGridItemProps, LayoutImage, Text } from '../../../../common';
import { LayoutImage } from '../../../../common/layout/LayoutImage';
import { Text } from '../../../../common/Text';
import { AchievementCategory } from '../../common/AchievementCategory';
export interface AchievementCategoryListItemViewProps extends LayoutGridItemProps export interface AchievementCategoryListItemViewProps extends LayoutGridItemProps
{ {

View File

@ -1,6 +1,6 @@
import { Dispatch, FC, SetStateAction } from 'react'; import { Dispatch, FC, SetStateAction } from 'react';
import { AutoGrid } from '../../../../common/AutoGrid'; import { AchievementCategory } from '../../../../api';
import { AchievementCategory } from '../../common/AchievementCategory'; import { AutoGrid } from '../../../../common';
import { AchievementsCategoryListItemView } from './AchievementsCategoryListItemView'; import { AchievementsCategoryListItemView } from './AchievementsCategoryListItemView';
export interface AchievementsCategoryListViewProps export interface AchievementsCategoryListViewProps

View File

@ -2,7 +2,7 @@ import { Dispose, DropBounce, EaseOut, FigureUpdateEvent, JumpBy, Motions, Nitro
import { FC, useCallback, useState } from 'react'; import { FC, useCallback, useState } from 'react';
import { CreateLinkEvent, GetSessionDataManager, GetUserProfile, OpenMessengerChat, VisitDesktop } from '../../api'; import { CreateLinkEvent, GetSessionDataManager, GetUserProfile, OpenMessengerChat, VisitDesktop } from '../../api';
import { Base, Flex, LayoutAvatarImageView, LayoutItemCountView, TransitionAnimation, TransitionAnimationTypes } from '../../common'; import { Base, Flex, LayoutAvatarImageView, LayoutItemCountView, TransitionAnimation, TransitionAnimationTypes } from '../../common';
import { AchievementsUIEvent, AchievementsUIUnseenCountEvent, FriendsEvent, FriendsMessengerIconEvent, FriendsRequestCountEvent, GuideToolEvent, InventoryEvent, ModToolsEvent, UnseenItemTrackerUpdateEvent, UserSettingsUIEvent } from '../../events'; import { AchievementsUIUnseenCountEvent, FriendsEvent, FriendsMessengerIconEvent, FriendsRequestCountEvent, GuideToolEvent, InventoryEvent, ModToolsEvent, UnseenItemTrackerUpdateEvent, UserSettingsUIEvent } from '../../events';
import { BatchUpdates, DispatchUiEvent, UseMessageEventHook, UseRoomEngineEvent, UseUiEvent } from '../../hooks'; import { BatchUpdates, DispatchUiEvent, UseMessageEventHook, UseRoomEngineEvent, UseUiEvent } from '../../hooks';
import { ToolbarViewItems } from './common/ToolbarViewItems'; import { ToolbarViewItems } from './common/ToolbarViewItems';
import { ToolbarMeView } from './ToolbarMeView'; import { ToolbarMeView } from './ToolbarMeView';
@ -157,7 +157,7 @@ export const ToolbarView: FC<ToolbarViewProps> = props =>
DispatchUiEvent(new ModToolsEvent(ModToolsEvent.TOGGLE_MOD_TOOLS)); DispatchUiEvent(new ModToolsEvent(ModToolsEvent.TOGGLE_MOD_TOOLS));
return; return;
case ToolbarViewItems.ACHIEVEMENTS_ITEM: case ToolbarViewItems.ACHIEVEMENTS_ITEM:
DispatchUiEvent(new AchievementsUIEvent(AchievementsUIEvent.TOGGLE_ACHIEVEMENTS)); CreateLinkEvent('achievements/toggle');
setMeExpanded(false); setMeExpanded(false);
return; return;
case ToolbarViewItems.PROFILE_ITEM: case ToolbarViewItems.PROFILE_ITEM: