mirror of
https://github.com/billsonnn/nitro-react.git
synced 2024-11-26 15:40:51 +01:00
Updates
This commit is contained in:
parent
ced2e2540e
commit
77cb36be44
@ -6,7 +6,7 @@ export const GetAchievementCategoryTotalUnseen = (category: IAchievementCategory
|
|||||||
|
|
||||||
let unseen = 0;
|
let unseen = 0;
|
||||||
|
|
||||||
for(const achievement of category.achievements) unseen += achievement.unseen;
|
for(const achievement of category.achievements) ((achievement.unseen > 0) && unseen++);
|
||||||
|
|
||||||
return unseen;
|
return unseen;
|
||||||
}
|
}
|
||||||
|
@ -1 +0,0 @@
|
|||||||
export * from './ProductImageUtility';
|
|
@ -1,13 +1,13 @@
|
|||||||
export * from './achievements';
|
export * from './achievements';
|
||||||
export * from './campaign';
|
export * from './campaign';
|
||||||
export * from './catalog';
|
export * from './catalog';
|
||||||
export * from './common';
|
|
||||||
export * from './core';
|
export * from './core';
|
||||||
export * from './friends';
|
export * from './friends';
|
||||||
export * from './GetRendererVersion';
|
export * from './GetRendererVersion';
|
||||||
export * from './GetUIVersion';
|
export * from './GetUIVersion';
|
||||||
export * from './groups';
|
export * from './groups';
|
||||||
export * from './inventory';
|
export * from './inventory';
|
||||||
|
export * from './inventory/unseen';
|
||||||
export * from './navigator';
|
export * from './navigator';
|
||||||
export * from './nitro';
|
export * from './nitro';
|
||||||
export * from './nitro/avatar';
|
export * from './nitro/avatar';
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { IFurnitureData, NitroEvent, ObjectDataFactory, PetFigureData, PetRespectComposer, PetSupplementComposer, PetType, RoomControllerLevel, RoomModerationSettings, RoomObjectCategory, RoomObjectOperationType, RoomObjectType, RoomObjectVariable, RoomSessionFavoriteGroupUpdateEvent, RoomSessionPetInfoUpdateEvent, RoomSessionUserBadgesEvent, RoomSessionUserFigureUpdateEvent, RoomTradingLevelEnum, RoomUnitDropHandItemComposer, RoomUnitGiveHandItemComposer, RoomUnitGiveHandItemPetComposer, RoomUserData, RoomWidgetEnum, RoomWidgetEnumItemExtradataParameter, Vector3d } from '@nitrots/nitro-renderer';
|
import { IFurnitureData, NitroEvent, ObjectDataFactory, PetFigureData, PetRespectComposer, PetSupplementComposer, PetType, RoomControllerLevel, RoomModerationSettings, RoomObjectCategory, RoomObjectOperationType, RoomObjectType, RoomObjectVariable, RoomSessionFavoriteGroupUpdateEvent, RoomSessionPetInfoUpdateEvent, RoomSessionUserBadgesEvent, RoomSessionUserFigureUpdateEvent, RoomTradingLevelEnum, RoomUnitDropHandItemComposer, RoomUnitGiveHandItemComposer, RoomUnitGiveHandItemPetComposer, RoomUserData, RoomWidgetEnum, RoomWidgetEnumItemExtradataParameter, TradingOpenComposer, Vector3d } from '@nitrots/nitro-renderer';
|
||||||
import { SendMessageComposer } from '../../..';
|
import { SendMessageComposer } from '../../..';
|
||||||
import { GetNitroInstance, GetRoomEngine, GetSessionDataManager, IsOwnerOfFurniture } from '../../../..';
|
import { GetNitroInstance, GetRoomEngine, GetSessionDataManager, IsOwnerOfFurniture } from '../../../..';
|
||||||
import { PetSupplementEnum } from '../../../../../components/room/widgets/avatar-info/common/PetSupplementEnum';
|
import { PetSupplementEnum } from '../../../../../components/room/widgets/avatar-info/common/PetSupplementEnum';
|
||||||
import { HelpReportUserEvent, InventoryTradeRequestEvent, WiredSelectObjectEvent } from '../../../../../events';
|
import { HelpReportUserEvent, WiredSelectObjectEvent } from '../../../../../events';
|
||||||
import { DispatchUiEvent } from '../../../../../hooks';
|
import { DispatchUiEvent } from '../../../../../hooks';
|
||||||
import { LocalizeText } from '../../../../utils/LocalizeText';
|
import { LocalizeText } from '../../../../utils/LocalizeText';
|
||||||
import { RoomWidgetObjectNameEvent, RoomWidgetUpdateChatInputContentEvent, RoomWidgetUpdateEvent, RoomWidgetUpdateInfostandFurniEvent, RoomWidgetUpdateInfostandPetEvent, RoomWidgetUpdateInfostandRentableBotEvent, RoomWidgetUpdateInfostandUserEvent } from '../events';
|
import { RoomWidgetObjectNameEvent, RoomWidgetUpdateChatInputContentEvent, RoomWidgetUpdateEvent, RoomWidgetUpdateInfostandFurniEvent, RoomWidgetUpdateInfostandPetEvent, RoomWidgetUpdateInfostandRentableBotEvent, RoomWidgetUpdateInfostandUserEvent } from '../events';
|
||||||
@ -119,7 +119,7 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
|
|||||||
this.container.roomSession.sendTakeRightsMessage((message as RoomWidgetUserActionMessage).userId);
|
this.container.roomSession.sendTakeRightsMessage((message as RoomWidgetUserActionMessage).userId);
|
||||||
break;
|
break;
|
||||||
case RoomWidgetUserActionMessage.START_TRADING:
|
case RoomWidgetUserActionMessage.START_TRADING:
|
||||||
DispatchUiEvent(new InventoryTradeRequestEvent(userData.roomIndex, userData.name));
|
SendMessageComposer(new TradingOpenComposer(userData.roomIndex));
|
||||||
break;
|
break;
|
||||||
// case RoomWidgetUserActionMessage.RWUAM_OPEN_HOME_PAGE:
|
// case RoomWidgetUserActionMessage.RWUAM_OPEN_HOME_PAGE:
|
||||||
// this._container.sessionDataManager._Str_21275((message as RoomWidgetUserActionMessage).userId, _local_3.name);
|
// this._container.sessionDataManager._Str_21275((message as RoomWidgetUserActionMessage).userId, _local_3.name);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { CatalogPageMessageProductData } from '@nitrots/nitro-renderer';
|
import { CatalogPageMessageProductData } from '@nitrots/nitro-renderer';
|
||||||
import { GetRoomEngine } from '..';
|
import { FurniCategory } from '../inventory';
|
||||||
import { FurniCategory } from '../../components/catalog/common/FurniCategory';
|
import { GetRoomEngine } from '../nitro';
|
||||||
|
|
||||||
export class ProductImageUtility
|
export class ProductImageUtility
|
||||||
{
|
{
|
@ -6,6 +6,7 @@ export * from './LocalizeFormattedNumber';
|
|||||||
export * from './LocalizeShortNumber';
|
export * from './LocalizeShortNumber';
|
||||||
export * from './LocalizeText';
|
export * from './LocalizeText';
|
||||||
export * from './PlaySound';
|
export * from './PlaySound';
|
||||||
|
export * from './ProductImageUtility';
|
||||||
export * from './Randomizer';
|
export * from './Randomizer';
|
||||||
export * from './RoomChatFormatter';
|
export * from './RoomChatFormatter';
|
||||||
export * from './SoundNames';
|
export * from './SoundNames';
|
||||||
|
@ -1,236 +1,69 @@
|
|||||||
import { AchievementData, AchievementEvent, AchievementsEvent, AchievementsScoreEvent, ILinkEventTracker, RequestAchievementsMessageComposer } from '@nitrots/nitro-renderer';
|
import { ILinkEventTracker } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
import { FC, useEffect, useMemo, useState } from 'react';
|
||||||
import { AchievementCategory, AddEventLinkTracker, CloneObject, GetAchievementCategoryImageUrl, GetAchievementIsIgnored, LocalizeText, RemoveLinkEventTracker, SendMessageComposer } from '../../api';
|
import { AddEventLinkTracker, GetAchievementCategoryImageUrl, LocalizeText, RemoveLinkEventTracker } from '../../api';
|
||||||
import { Base, Column, LayoutImage, LayoutProgressBar, NitroCardContentView, NitroCardHeaderView, NitroCardSubHeaderView, NitroCardView, Text } from '../../common';
|
import { Base, Column, LayoutImage, LayoutProgressBar, NitroCardContentView, NitroCardHeaderView, NitroCardSubHeaderView, NitroCardView, Text } from '../../common';
|
||||||
import { AchievementsUIUnseenCountEvent } from '../../events';
|
import { useAchievements } from '../../hooks';
|
||||||
import { DispatchUiEvent, UseMessageEventHook } from '../../hooks';
|
|
||||||
import { AchievementCategoryView } from './views/AchievementCategoryView';
|
import { AchievementCategoryView } from './views/AchievementCategoryView';
|
||||||
import { AchievementsCategoryListView } from './views/category-list/AchievementsCategoryListView';
|
import { AchievementsCategoryListView } from './views/category-list/AchievementsCategoryListView';
|
||||||
|
|
||||||
export const AchievementsView: FC<{}> = props =>
|
export const AchievementsView: FC<{}> = props =>
|
||||||
{
|
{
|
||||||
const [ isVisible, setIsVisible ] = useState(false);
|
const [ isVisible, setIsVisible ] = useState(false);
|
||||||
const [ isInitalized, setIsInitalized ] = useState(false);
|
const { achievementCategories = [], selectedCategoryCode = null, setSelectedCategoryCode = null, selectedAchievementId = -1, setSelectedAchievementId = null, achievementScore = 0, getProgress = 0, getMaxProgress = 0, setAchievementSeen = null } = useAchievements();
|
||||||
const [ achievementCategories, setAchievementCategories ] = useState<AchievementCategory[]>([]);
|
|
||||||
const [ selectedCategoryCode, setSelectedCategoryCode ] = useState<string>(null);
|
|
||||||
const [ achievementScore, setAchievementScore ] = useState(0);
|
|
||||||
|
|
||||||
const onAchievementEvent = useCallback((event: AchievementEvent) =>
|
const selectedCategory = useMemo(() =>
|
||||||
{
|
{
|
||||||
const parser = event.getParser();
|
if(selectedCategoryCode === null) return null;
|
||||||
const achievement = parser.achievement;
|
|
||||||
const categoryName = achievement.category;
|
|
||||||
|
|
||||||
setAchievementCategories(prevValue =>
|
return achievementCategories.find(category => (category.code === selectedCategoryCode));
|
||||||
{
|
|
||||||
const newValue = [ ...prevValue ];
|
|
||||||
const categoryIndex = newValue.findIndex(existing => (existing.code === categoryName));
|
|
||||||
|
|
||||||
if(categoryIndex === -1)
|
|
||||||
{
|
|
||||||
const category = new AchievementCategory(categoryName);
|
|
||||||
|
|
||||||
category.achievements.push(achievement);
|
|
||||||
|
|
||||||
newValue.push(category);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const category = CloneObject(newValue[categoryIndex]);
|
|
||||||
const newAchievements = [ ...category.achievements ];
|
|
||||||
const achievementIndex = newAchievements.findIndex(existing => (existing.achievementId === achievement.achievementId));
|
|
||||||
let previousAchievement: AchievementData = null;
|
|
||||||
|
|
||||||
if(achievementIndex === -1)
|
|
||||||
{
|
|
||||||
newAchievements.push(achievement);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
previousAchievement = newAchievements[achievementIndex];
|
|
||||||
|
|
||||||
newAchievements[achievementIndex] = achievement;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!GetAchievementIsIgnored(achievement))
|
|
||||||
{
|
|
||||||
achievement.unseen++;
|
|
||||||
|
|
||||||
if(previousAchievement) achievement.unseen += previousAchievement.unseen;
|
|
||||||
}
|
|
||||||
|
|
||||||
category.achievements = newAchievements;
|
|
||||||
|
|
||||||
newValue[categoryIndex] = category;
|
|
||||||
}
|
|
||||||
|
|
||||||
return newValue;
|
|
||||||
});
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
UseMessageEventHook(AchievementEvent, onAchievementEvent);
|
|
||||||
|
|
||||||
const onAchievementsEvent = useCallback((event: AchievementsEvent) =>
|
|
||||||
{
|
|
||||||
const parser = event.getParser();
|
|
||||||
|
|
||||||
const categories: AchievementCategory[] = [];
|
|
||||||
|
|
||||||
for(const achievement of parser.achievements)
|
|
||||||
{
|
|
||||||
const categoryName = achievement.category;
|
|
||||||
|
|
||||||
let existing = categories.find(category => (category.code === categoryName));
|
|
||||||
|
|
||||||
if(!existing)
|
|
||||||
{
|
|
||||||
existing = new AchievementCategory(categoryName);
|
|
||||||
|
|
||||||
categories.push(existing);
|
|
||||||
}
|
|
||||||
|
|
||||||
existing.achievements.push(achievement);
|
|
||||||
}
|
|
||||||
|
|
||||||
setAchievementCategories(categories);
|
|
||||||
setIsInitalized(true);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
UseMessageEventHook(AchievementsEvent, onAchievementsEvent);
|
|
||||||
|
|
||||||
const onAchievementsScoreEvent = useCallback((event: AchievementsScoreEvent) =>
|
|
||||||
{
|
|
||||||
const parser = event.getParser();
|
|
||||||
|
|
||||||
setAchievementScore(parser.score);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
UseMessageEventHook(AchievementsScoreEvent, onAchievementsScoreEvent);
|
|
||||||
|
|
||||||
const getTotalUnseen = useMemo(() =>
|
|
||||||
{
|
|
||||||
let unseen = 0;
|
|
||||||
|
|
||||||
for(const category of achievementCategories)
|
|
||||||
{
|
|
||||||
for(const achievement of category.achievements) unseen += achievement.unseen;
|
|
||||||
}
|
|
||||||
|
|
||||||
return unseen;
|
|
||||||
}, [ achievementCategories ]);
|
|
||||||
|
|
||||||
const getProgress = useMemo(() =>
|
|
||||||
{
|
|
||||||
let progress = 0;
|
|
||||||
|
|
||||||
for(const category of achievementCategories) progress += category.getProgress();
|
|
||||||
|
|
||||||
return progress;
|
|
||||||
}, [ achievementCategories ]);
|
|
||||||
|
|
||||||
const getMaxProgress = useMemo(() =>
|
|
||||||
{
|
|
||||||
let progress = 0;
|
|
||||||
|
|
||||||
for(const category of achievementCategories) progress += category.getMaxProgress();
|
|
||||||
|
|
||||||
return progress;
|
|
||||||
}, [ achievementCategories ]);
|
|
||||||
|
|
||||||
const scaledProgressPercent = useMemo(() =>
|
|
||||||
{
|
|
||||||
return ~~((((getProgress - 0) * (100 - 0)) / (getMaxProgress - 0)) + 0);
|
|
||||||
}, [ getProgress, getMaxProgress ]);
|
|
||||||
|
|
||||||
const getSelectedCategory = useMemo(() =>
|
|
||||||
{
|
|
||||||
if(!achievementCategories || !achievementCategories.length) return null;
|
|
||||||
|
|
||||||
return achievementCategories.find(existing => (existing.code === selectedCategoryCode));
|
|
||||||
}, [ achievementCategories, selectedCategoryCode ]);
|
}, [ achievementCategories, selectedCategoryCode ]);
|
||||||
|
|
||||||
const setAchievementSeen = useCallback((code: string, achievementId: number) =>
|
|
||||||
{
|
|
||||||
setAchievementCategories(prevValue =>
|
|
||||||
{
|
|
||||||
const newValue = [ ...prevValue ];
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
const linkTracker: ILinkEventTracker = {
|
const linkTracker: ILinkEventTracker = {
|
||||||
linkReceived,
|
linkReceived: (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;
|
||||||
|
}
|
||||||
|
},
|
||||||
eventUrlPrefix: 'achievements/'
|
eventUrlPrefix: 'achievements/'
|
||||||
};
|
};
|
||||||
|
|
||||||
AddEventLinkTracker(linkTracker);
|
AddEventLinkTracker(linkTracker);
|
||||||
|
|
||||||
return () => RemoveLinkEventTracker(linkTracker);
|
return () => RemoveLinkEventTracker(linkTracker);
|
||||||
}, [ linkReceived ]);
|
}, []);
|
||||||
|
|
||||||
useEffect(() =>
|
if(!isVisible) return null;
|
||||||
{
|
|
||||||
if(!isVisible || isInitalized) return;
|
|
||||||
|
|
||||||
SendMessageComposer(new RequestAchievementsMessageComposer());
|
|
||||||
}, [ isVisible, isInitalized ]);
|
|
||||||
|
|
||||||
useEffect(() =>
|
|
||||||
{
|
|
||||||
DispatchUiEvent(new AchievementsUIUnseenCountEvent(getTotalUnseen));
|
|
||||||
}, [ getTotalUnseen ]);
|
|
||||||
|
|
||||||
if(!isVisible || !isInitalized) return null;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NitroCardView uniqueKey="achievements" className="nitro-achievements" theme="primary-slim">
|
<NitroCardView uniqueKey="achievements" className="nitro-achievements" theme="primary-slim">
|
||||||
<NitroCardHeaderView headerText={ LocalizeText('inventory.achievements') } onCloseClick={ event => setIsVisible(false) } />
|
<NitroCardHeaderView headerText={ LocalizeText('inventory.achievements') } onCloseClick={ event => setIsVisible(false) } />
|
||||||
{ getSelectedCategory &&
|
{ selectedCategory &&
|
||||||
<NitroCardSubHeaderView position="relative" className="justify-content-center align-items-center cursor-pointer" gap={ 3 }>
|
<NitroCardSubHeaderView position="relative" className="justify-content-center align-items-center cursor-pointer" gap={ 3 }>
|
||||||
<Base onClick={ event => setSelectedCategoryCode(null) } className="nitro-achievements-back-arrow" />
|
<Base onClick={ event => setSelectedCategoryCode(null) } className="nitro-achievements-back-arrow" />
|
||||||
<Column grow gap={ 0 }>
|
<Column grow gap={ 0 }>
|
||||||
<Text fontSize={ 4 } fontWeight="bold" className="text-small">{ LocalizeText(`quests.${ getSelectedCategory.code }.name`) }</Text>
|
<Text fontSize={ 4 } fontWeight="bold" className="text-small">{ LocalizeText(`quests.${ selectedCategory.code }.name`) }</Text>
|
||||||
<Text>{ LocalizeText('achievements.details.categoryprogress', [ 'progress', 'limit' ], [ getSelectedCategory.getProgress().toString(), getSelectedCategory.getMaxProgress().toString() ]) }</Text>
|
<Text>{ LocalizeText('achievements.details.categoryprogress', [ 'progress', 'limit' ], [ selectedCategory.getProgress().toString(), selectedCategory.getMaxProgress().toString() ]) }</Text>
|
||||||
</Column>
|
</Column>
|
||||||
<LayoutImage imageUrl={ GetAchievementCategoryImageUrl(getSelectedCategory, null,true) } />
|
<LayoutImage imageUrl={ GetAchievementCategoryImageUrl(selectedCategory, null,true) } />
|
||||||
</NitroCardSubHeaderView> }
|
</NitroCardSubHeaderView> }
|
||||||
<NitroCardContentView gap={ 1 }>
|
<NitroCardContentView gap={ 1 }>
|
||||||
{ !getSelectedCategory &&
|
{ !selectedCategory &&
|
||||||
<>
|
<>
|
||||||
<AchievementsCategoryListView categories={ achievementCategories } selectedCategoryCode={ selectedCategoryCode } setSelectedCategoryCode={ setSelectedCategoryCode } />
|
<AchievementsCategoryListView categories={ achievementCategories } selectedCategoryCode={ selectedCategoryCode } setSelectedCategoryCode={ setSelectedCategoryCode } />
|
||||||
<Column grow justifyContent="end" gap={ 1 }>
|
<Column grow justifyContent="end" gap={ 1 }>
|
||||||
@ -238,8 +71,8 @@ export const AchievementsView: FC<{}> = props =>
|
|||||||
<LayoutProgressBar text={ LocalizeText('achievements.categories.totalprogress', [ 'progress', 'limit' ], [ getProgress.toString(), getMaxProgress.toString() ]) } progress={ getProgress } maxProgress={ getMaxProgress } />
|
<LayoutProgressBar text={ LocalizeText('achievements.categories.totalprogress', [ 'progress', 'limit' ], [ getProgress.toString(), getMaxProgress.toString() ]) } progress={ getProgress } maxProgress={ getMaxProgress } />
|
||||||
</Column>
|
</Column>
|
||||||
</> }
|
</> }
|
||||||
{ getSelectedCategory &&
|
{ selectedCategory &&
|
||||||
<AchievementCategoryView category={ getSelectedCategory } setAchievementSeen={ setAchievementSeen } /> }
|
<AchievementCategoryView category={ selectedCategory } selectedAchievementId={ selectedAchievementId } setSelectedAchievementId={ setSelectedAchievementId } setAchievementSeen={ setAchievementSeen } /> }
|
||||||
</NitroCardContentView>
|
</NitroCardContentView>
|
||||||
</NitroCardView>
|
</NitroCardView>
|
||||||
);
|
);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { FC, useEffect, useMemo, useState } from 'react';
|
import { Dispatch, FC, SetStateAction, useEffect, useMemo } from 'react';
|
||||||
import { AchievementCategory } from '../../../api';
|
import { AchievementCategory } from '../../../api';
|
||||||
import { Column } from '../../../common';
|
import { Column } from '../../../common';
|
||||||
import { AchievementListView } from './achievement-list/AchievementListView';
|
import { AchievementListView } from './achievement-list/AchievementListView';
|
||||||
@ -7,40 +7,44 @@ import { AchievementDetailsView } from './AchievementDetailsView';
|
|||||||
interface AchievementCategoryViewProps
|
interface AchievementCategoryViewProps
|
||||||
{
|
{
|
||||||
category: AchievementCategory;
|
category: AchievementCategory;
|
||||||
|
selectedAchievementId: number;
|
||||||
|
setSelectedAchievementId: Dispatch<SetStateAction<number>>;
|
||||||
setAchievementSeen: (code: string, achievementId: number) => void;
|
setAchievementSeen: (code: string, achievementId: number) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AchievementCategoryView: FC<AchievementCategoryViewProps> = props =>
|
export const AchievementCategoryView: FC<AchievementCategoryViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { category = null, setAchievementSeen = null } = props;
|
const { category = null, selectedAchievementId = -1, setSelectedAchievementId = null, setAchievementSeen = null } = props;
|
||||||
const [ selectedAchievementId, setSelectedAchievementId ] = useState(0);
|
|
||||||
|
|
||||||
const getSelectedAchievement = useMemo(() =>
|
const selectedAchievement = useMemo(() =>
|
||||||
{
|
{
|
||||||
if(!category || !category.achievements.length) return null;
|
if(selectedAchievementId === -1) return null;
|
||||||
|
|
||||||
return category.achievements.find(existing => (existing.achievementId === selectedAchievementId));
|
return category.achievements.find(achievement => (achievement.achievementId === selectedAchievementId));
|
||||||
}, [ category, selectedAchievementId ]);
|
}, [ category, selectedAchievementId ]);
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
setSelectedAchievementId((!category || !category.achievements.length) ? 0 : category.achievements[0].achievementId);
|
if(!selectedAchievement)
|
||||||
}, [ category ]);
|
{
|
||||||
|
if(category.achievements.length) setSelectedAchievementId(category.achievements[0].achievementId);
|
||||||
|
}
|
||||||
|
}, [ selectedAchievement, category, setSelectedAchievementId ]);
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
if(!getSelectedAchievement || !getSelectedAchievement.unseen) return;
|
if(!selectedAchievement) return;
|
||||||
|
|
||||||
setAchievementSeen(category.code, getSelectedAchievement.achievementId);
|
setAchievementSeen(category.code, selectedAchievement.achievementId);
|
||||||
}, [ category, getSelectedAchievement, setAchievementSeen ]);
|
}, [ selectedAchievement, category, setAchievementSeen ]);
|
||||||
|
|
||||||
if(!category) return null;
|
if(!category) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Column fullHeight justifyContent="between">
|
<Column fullHeight justifyContent="between">
|
||||||
<AchievementListView achievements={ category.achievements } selectedAchievementId={ selectedAchievementId } setSelectedAchievementId={ setSelectedAchievementId } />
|
<AchievementListView achievements={ category.achievements } selectedAchievementId={ selectedAchievementId } setSelectedAchievementId={ setSelectedAchievementId } />
|
||||||
{ getSelectedAchievement &&
|
{ !!selectedAchievement &&
|
||||||
<AchievementDetailsView achievement={ getSelectedAchievement } /> }
|
<AchievementDetailsView achievement={ selectedAchievement } /> }
|
||||||
</Column>
|
</Column>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -11,12 +11,12 @@ interface AchievementDetailsViewProps
|
|||||||
|
|
||||||
export const AchievementDetailsView: FC<AchievementDetailsViewProps> = props =>
|
export const AchievementDetailsView: FC<AchievementDetailsViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { achievement = null } = props;
|
const { achievement = null, children = null, ...rest } = props;
|
||||||
|
|
||||||
if(!achievement) return null;
|
if(!achievement) return null;
|
||||||
|
|
||||||
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" { ...rest }>
|
||||||
<Column center gap={ 1 }>
|
<Column center gap={ 1 }>
|
||||||
<AchievementBadgeView className="nitro-achievements-badge-image" achievement={ achievement } scale={ 2 } />
|
<AchievementBadgeView className="nitro-achievements-badge-image" achievement={ achievement } scale={ 2 } />
|
||||||
<Text fontWeight="bold">
|
<Text fontWeight="bold">
|
||||||
@ -48,6 +48,7 @@ export const AchievementDetailsView: FC<AchievementDetailsViewProps> = props =>
|
|||||||
<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) } /> }
|
<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> }
|
||||||
</Column>
|
</Column>
|
||||||
|
{ children }
|
||||||
</Flex>
|
</Flex>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,23 @@
|
|||||||
import { AchievementData } from '@nitrots/nitro-renderer';
|
import { AchievementData } from '@nitrots/nitro-renderer';
|
||||||
import { FC } from 'react';
|
import { Dispatch, FC, SetStateAction } from 'react';
|
||||||
import { LayoutGridItem, LayoutGridItemProps } from '../../../../common';
|
import { LayoutGridItem } from '../../../../common';
|
||||||
import { AchievementBadgeView } from '../AchievementBadgeView';
|
import { AchievementBadgeView } from '../AchievementBadgeView';
|
||||||
|
|
||||||
interface AchievementListItemViewProps extends LayoutGridItemProps
|
interface AchievementListItemViewProps
|
||||||
{
|
{
|
||||||
achievement: AchievementData;
|
achievement: AchievementData;
|
||||||
|
selectedAchievementId: number;
|
||||||
|
setSelectedAchievementId: Dispatch<SetStateAction<number>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AchievementListItemView: FC<AchievementListItemViewProps> = props =>
|
export const AchievementListItemView: FC<AchievementListItemViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { achievement = null, children = null, ...rest } = props;
|
const { achievement = null, selectedAchievementId = -1, setSelectedAchievementId = null, children = null, ...rest } = props;
|
||||||
|
|
||||||
if(!achievement) return null;
|
if(!achievement) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LayoutGridItem itemCount={ achievement.unseen } itemCountMinimum={ 0 } { ...rest }>
|
<LayoutGridItem itemActive={ (selectedAchievementId === achievement.achievementId) } itemUnseen={ (achievement.unseen > 0) } onClick={ event => setSelectedAchievementId(achievement.achievementId) } { ...rest }>
|
||||||
<AchievementBadgeView achievement={ achievement } />
|
<AchievementBadgeView achievement={ achievement } />
|
||||||
{ children }
|
{ children }
|
||||||
</LayoutGridItem>
|
</LayoutGridItem>
|
||||||
|
@ -3,7 +3,7 @@ import { Dispatch, FC, SetStateAction } from 'react';
|
|||||||
import { AutoGrid } from '../../../../common';
|
import { AutoGrid } from '../../../../common';
|
||||||
import { AchievementListItemView } from './AchievementListItemView';
|
import { AchievementListItemView } from './AchievementListItemView';
|
||||||
|
|
||||||
export interface AchievementListViewProps
|
interface AchievementListViewProps
|
||||||
{
|
{
|
||||||
achievements: AchievementData[];
|
achievements: AchievementData[];
|
||||||
selectedAchievementId: number;
|
selectedAchievementId: number;
|
||||||
@ -12,11 +12,11 @@ export interface AchievementListViewProps
|
|||||||
|
|
||||||
export const AchievementListView: FC<AchievementListViewProps> = props =>
|
export const AchievementListView: FC<AchievementListViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { achievements = null, selectedAchievementId = 0, setSelectedAchievementId = null, children = null } = props;
|
const { achievements = null, selectedAchievementId = -1, setSelectedAchievementId = null, children = null, ...rest } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AutoGrid columnCount={ 6 } columnMinWidth={ 50 } columnMinHeight={ 50 }>
|
<AutoGrid columnCount={ 6 } columnMinWidth={ 50 } columnMinHeight={ 50 } { ...rest }>
|
||||||
{ achievements && (achievements.length > 0) && achievements.map((achievement, index) => <AchievementListItemView key={ index } achievement={ achievement } itemActive={ (selectedAchievementId === achievement.achievementId) } itemUnseen={ (achievement.unseen > 0) } onClick={ event => setSelectedAchievementId(achievement.achievementId) } />) }
|
{ achievements && (achievements.length > 0) && achievements.map((achievement, index) => <AchievementListItemView key={ index } achievement={ achievement } selectedAchievementId={ selectedAchievementId } setSelectedAchievementId={ setSelectedAchievementId } />) }
|
||||||
{ children }
|
{ children }
|
||||||
</AutoGrid>
|
</AutoGrid>
|
||||||
);
|
);
|
||||||
|
@ -1,15 +1,19 @@
|
|||||||
import { FC } from 'react';
|
import { Dispatch, FC, SetStateAction } from 'react';
|
||||||
import { GetAchievementCategoryImageUrl, GetAchievementCategoryMaxProgress, GetAchievementCategoryProgress, GetAchievementCategoryTotalUnseen, IAchievementCategory, LocalizeText } from '../../../../api';
|
import { GetAchievementCategoryImageUrl, GetAchievementCategoryMaxProgress, GetAchievementCategoryProgress, GetAchievementCategoryTotalUnseen, IAchievementCategory, LocalizeText } from '../../../../api';
|
||||||
import { LayoutBackgroundImage, LayoutGridItem, LayoutGridItemProps, Text } from '../../../../common';
|
import { LayoutBackgroundImage, LayoutGridItem, Text } from '../../../../common';
|
||||||
|
|
||||||
export interface AchievementCategoryListItemViewProps extends LayoutGridItemProps
|
interface AchievementCategoryListItemViewProps
|
||||||
{
|
{
|
||||||
category: IAchievementCategory;
|
category: IAchievementCategory;
|
||||||
|
selectedCategoryCode: string;
|
||||||
|
setSelectedCategoryCode: Dispatch<SetStateAction<string>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AchievementsCategoryListItemView: FC<AchievementCategoryListItemViewProps> = props =>
|
export const AchievementsCategoryListItemView: FC<AchievementCategoryListItemViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { category = null, children = null, ...rest } = props;
|
const { category = null, selectedCategoryCode = null, setSelectedCategoryCode = null, children = null, ...rest } = props;
|
||||||
|
|
||||||
|
if(!category) return null;
|
||||||
|
|
||||||
const progress = GetAchievementCategoryProgress(category);
|
const progress = GetAchievementCategoryProgress(category);
|
||||||
const maxProgress = GetAchievementCategoryMaxProgress(category);
|
const maxProgress = GetAchievementCategoryMaxProgress(category);
|
||||||
@ -17,9 +21,9 @@ export const AchievementsCategoryListItemView: FC<AchievementCategoryListItemVie
|
|||||||
const getTotalUnseen = GetAchievementCategoryTotalUnseen(category);
|
const getTotalUnseen = GetAchievementCategoryTotalUnseen(category);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LayoutGridItem itemCount={ getTotalUnseen } itemCountMinimum={ 0 } gap={ 1 } { ...rest }>
|
<LayoutGridItem itemActive={ (selectedCategoryCode === category.code) } itemCount={ getTotalUnseen } itemCountMinimum={ 0 } gap={ 1 } onClick={ event => setSelectedCategoryCode(category.code) } { ...rest }>
|
||||||
<Text fullWidth center className="small pt-1">{ LocalizeText(`quests.${ category.code }.name`) }</Text>
|
<Text fullWidth center small className="pt-1">{ LocalizeText(`quests.${ category.code }.name`) }</Text>
|
||||||
<LayoutBackgroundImage className="position-relative" imageUrl={ getCategoryImage }>
|
<LayoutBackgroundImage position="relative" imageUrl={ getCategoryImage }>
|
||||||
<Text fullWidth center position="absolute" variant="white" style={ { fontSize: 12, bottom: 9 } }>{ progress } / { maxProgress }</Text>
|
<Text fullWidth center position="absolute" variant="white" style={ { fontSize: 12, bottom: 9 } }>{ progress } / { maxProgress }</Text>
|
||||||
</LayoutBackgroundImage>
|
</LayoutBackgroundImage>
|
||||||
{ children }
|
{ children }
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { Dispatch, FC, SetStateAction } from 'react';
|
import { Dispatch, FC, SetStateAction } from 'react';
|
||||||
import { IAchievementCategory } from '../../../../api';
|
import { IAchievementCategory } from '../../../../api';
|
||||||
import { AutoGrid, AutoGridProps } from '../../../../common';
|
import { AutoGrid } from '../../../../common';
|
||||||
import { AchievementsCategoryListItemView } from './AchievementsCategoryListItemView';
|
import { AchievementsCategoryListItemView } from './AchievementsCategoryListItemView';
|
||||||
|
|
||||||
export interface AchievementsCategoryListViewProps extends AutoGridProps
|
interface AchievementsCategoryListViewProps
|
||||||
{
|
{
|
||||||
categories: IAchievementCategory[];
|
categories: IAchievementCategory[];
|
||||||
selectedCategoryCode: string;
|
selectedCategoryCode: string;
|
||||||
@ -12,11 +12,11 @@ export interface AchievementsCategoryListViewProps extends AutoGridProps
|
|||||||
|
|
||||||
export const AchievementsCategoryListView: FC<AchievementsCategoryListViewProps> = props =>
|
export const AchievementsCategoryListView: FC<AchievementsCategoryListViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { categories = null, selectedCategoryCode = null, setSelectedCategoryCode = null, columnCount = 3, columnMinWidth = 90, columnMinHeight = 100, children = null, ...rest } = props;
|
const { categories = null, selectedCategoryCode = null, setSelectedCategoryCode = null, children = null, ...rest } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AutoGrid columnCount={ columnCount } columnMinWidth={ columnMinWidth } columnMinHeight={ columnMinHeight } { ...rest }>
|
<AutoGrid columnCount={ 3 } columnMinWidth={ 90 } columnMinHeight={ 100 } { ...rest }>
|
||||||
{ categories && (categories.length > 0) && categories.map((category, index) => <AchievementsCategoryListItemView key={ index } category={ category } itemActive={ (selectedCategoryCode === category.code) } onClick={ event => setSelectedCategoryCode(category.code) } /> ) }
|
{ categories && (categories.length > 0) && categories.map((category, index) => <AchievementsCategoryListItemView key={ index } category={ category } selectedCategoryCode={ selectedCategoryCode } setSelectedCategoryCode={ setSelectedCategoryCode } /> ) }
|
||||||
{ children }
|
{ children }
|
||||||
</AutoGrid>
|
</AutoGrid>
|
||||||
);
|
);
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import { CameraPublishStatusMessageEvent, CameraPurchaseOKMessageEvent, CameraStorageUrlMessageEvent, PublishPhotoMessageComposer, PurchasePhotoMessageComposer } from '@nitrots/nitro-renderer';
|
import { CameraPublishStatusMessageEvent, CameraPurchaseOKMessageEvent, CameraStorageUrlMessageEvent, PublishPhotoMessageComposer, PurchasePhotoMessageComposer } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import { GetConfiguration, GetRoomEngine, LocalizeText, SendMessageComposer } from '../../../../api';
|
import { CreateLinkEvent, GetConfiguration, GetRoomEngine, LocalizeText, SendMessageComposer } from '../../../../api';
|
||||||
import { Button, Column, Flex, LayoutCurrencyIcon, LayoutImage, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common';
|
import { Button, Column, Flex, LayoutCurrencyIcon, LayoutImage, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common';
|
||||||
import { InventoryEvent } from '../../../../events';
|
import { UseMessageEventHook } from '../../../../hooks';
|
||||||
import { DispatchUiEvent, UseMessageEventHook } from '../../../../hooks';
|
|
||||||
|
|
||||||
export interface CameraWidgetCheckoutViewProps
|
export interface CameraWidgetCheckoutViewProps
|
||||||
{
|
{
|
||||||
@ -122,7 +121,7 @@ export const CameraWidgetCheckoutView: FC<CameraWidgetCheckoutViewProps> = props
|
|||||||
{ (picturesBought > 0) &&
|
{ (picturesBought > 0) &&
|
||||||
<Text>
|
<Text>
|
||||||
<Text bold>{ LocalizeText('camera.purchase.count.info') }</Text> { picturesBought }
|
<Text bold>{ LocalizeText('camera.purchase.count.info') }</Text> { picturesBought }
|
||||||
<u className="ms-1 cursor-pointer" onClick={ () => DispatchUiEvent(new InventoryEvent(InventoryEvent.SHOW_INVENTORY)) }>{ LocalizeText('camera.open.inventory') }</u>
|
<u className="ms-1 cursor-pointer" onClick={ () => CreateLinkEvent('inventory/open') }>{ LocalizeText('camera.open.inventory') }</u>
|
||||||
</Text> }
|
</Text> }
|
||||||
</Column>
|
</Column>
|
||||||
<Flex alignItems="center">
|
<Flex alignItems="center">
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
import { BadgesEvent, ClubGiftInfoEvent, FigureUpdateEvent, FriendlyTime, GetClubGiftInfo, ILinkEventTracker, RequestBadgesComposer, ScrGetKickbackInfoMessageComposer, ScrKickbackData, ScrSendKickbackInfoMessageEvent, UserInfoEvent, UserSubscriptionEvent } from '@nitrots/nitro-renderer';
|
import { BadgesEvent, ClubGiftInfoEvent, FriendlyTime, GetClubGiftInfo, ILinkEventTracker, RequestBadgesComposer, ScrGetKickbackInfoMessageComposer, ScrKickbackData, ScrSendKickbackInfoMessageEvent, UserSubscriptionEvent } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback, useEffect, useState } from 'react';
|
import { FC, useCallback, useEffect, useState } from 'react';
|
||||||
import { OverlayTrigger, Popover } from 'react-bootstrap';
|
import { OverlayTrigger, Popover } from 'react-bootstrap';
|
||||||
import { AddEventLinkTracker, CreateLinkEvent, GetConfiguration, LocalizeText, RemoveLinkEventTracker, SendMessageComposer } from '../../api';
|
import { AddEventLinkTracker, CreateLinkEvent, GetConfiguration, LocalizeText, RemoveLinkEventTracker, SendMessageComposer } from '../../api';
|
||||||
import { Base, Button, Column, Flex, LayoutAvatarImageView, LayoutBadgeImageView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../common';
|
import { Base, Button, Column, Flex, LayoutAvatarImageView, LayoutBadgeImageView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../common';
|
||||||
import { HcCenterEvent } from '../../events';
|
import { UseMessageEventHook, useSessionInfo } from '../../hooks';
|
||||||
import { UseMessageEventHook, UseUiEvent } from '../../hooks';
|
|
||||||
import { BadgeResolver } from './common/BadgeResolver';
|
import { BadgeResolver } from './common/BadgeResolver';
|
||||||
import { ClubStatus } from './common/ClubStatus';
|
import { ClubStatus } from './common/ClubStatus';
|
||||||
|
|
||||||
@ -12,7 +11,6 @@ import { ClubStatus } from './common/ClubStatus';
|
|||||||
export const HcCenterView: FC<{}> = props =>
|
export const HcCenterView: FC<{}> = props =>
|
||||||
{
|
{
|
||||||
const [ isVisible, setIsVisible ] = useState(false);
|
const [ isVisible, setIsVisible ] = useState(false);
|
||||||
const [ userFigure, setUserFigure ] = useState<string>(null);
|
|
||||||
const [ kickbackData, setKickbackData ] = useState<ScrKickbackData>(null);
|
const [ kickbackData, setKickbackData ] = useState<ScrKickbackData>(null);
|
||||||
const [ clubDays, setClubDays ] = useState(0);
|
const [ clubDays, setClubDays ] = useState(0);
|
||||||
const [ pastClubDays, setPastClubDays ] = useState(0);
|
const [ pastClubDays, setPastClubDays ] = useState(0);
|
||||||
@ -21,6 +19,7 @@ export const HcCenterView: FC<{}> = props =>
|
|||||||
const [ clubStatus, setClubStatus ] = useState(ClubStatus.NONE);
|
const [ clubStatus, setClubStatus ] = useState(ClubStatus.NONE);
|
||||||
const [ unclaimedGifts, setUnclaimedGifts ] = useState(0);
|
const [ unclaimedGifts, setUnclaimedGifts ] = useState(0);
|
||||||
const [ badgeCode, setBadgeCode ] = useState(BadgeResolver.default_badge);
|
const [ badgeCode, setBadgeCode ] = useState(BadgeResolver.default_badge);
|
||||||
|
const { userFigure = null } = useSessionInfo();
|
||||||
|
|
||||||
const getClubText = () =>
|
const getClubText = () =>
|
||||||
{
|
{
|
||||||
@ -64,36 +63,6 @@ export const HcCenterView: FC<{}> = props =>
|
|||||||
return LocalizeText('hccenter.special.sum', [ 'credits' ], [ (kickbackData.creditRewardForStreakBonus + kickbackData.creditRewardForMonthlySpent).toString() ]);
|
return LocalizeText('hccenter.special.sum', [ 'credits' ], [ (kickbackData.creditRewardForStreakBonus + kickbackData.creditRewardForMonthlySpent).toString() ]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const onUserInfoEvent = useCallback((event: UserInfoEvent) =>
|
|
||||||
{
|
|
||||||
const parser = event.getParser();
|
|
||||||
|
|
||||||
setUserFigure(parser.userInfo.figure);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
UseMessageEventHook(UserInfoEvent, onUserInfoEvent);
|
|
||||||
|
|
||||||
const onUserFigureEvent = useCallback((event: FigureUpdateEvent) =>
|
|
||||||
{
|
|
||||||
const parser = event.getParser();
|
|
||||||
|
|
||||||
setUserFigure(parser.figure);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
UseMessageEventHook(FigureUpdateEvent, onUserFigureEvent);
|
|
||||||
|
|
||||||
const onHcCenterEvent = useCallback((event: HcCenterEvent) =>
|
|
||||||
{
|
|
||||||
switch(event.type)
|
|
||||||
{
|
|
||||||
case HcCenterEvent.TOGGLE_HC_CENTER:
|
|
||||||
setIsVisible(!isVisible);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}, [ isVisible ]);
|
|
||||||
|
|
||||||
UseUiEvent(HcCenterEvent.TOGGLE_HC_CENTER, onHcCenterEvent);
|
|
||||||
|
|
||||||
const onClubGiftInfoEvent = useCallback((event: ClubGiftInfoEvent) =>
|
const onClubGiftInfoEvent = useCallback((event: ClubGiftInfoEvent) =>
|
||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
@ -265,7 +234,7 @@ export const HcCenterView: FC<{}> = props =>
|
|||||||
<h5 className="ms-2 mb-1 bolder">{LocalizeText('hccenter.special.amount.title')}</h5>
|
<h5 className="ms-2 mb-1 bolder">{LocalizeText('hccenter.special.amount.title')}</h5>
|
||||||
<div className="d-flex flex-column">
|
<div className="d-flex flex-column">
|
||||||
<div className="w-100 text-center ms-4n">{getHcPaydayAmount()}</div>
|
<div className="w-100 text-center ms-4n">{getHcPaydayAmount()}</div>
|
||||||
<OverlayTrigger trigger="hover" placement="left" overlay={popover}>
|
<OverlayTrigger trigger={ [ 'hover', 'focus' ] } placement="left" overlay={popover}>
|
||||||
<div className="btn btn-link align-self-end text-primary">
|
<div className="btn btn-link align-self-end text-primary">
|
||||||
{LocalizeText('hccenter.breakdown.infolink')}
|
{LocalizeText('hccenter.breakdown.infolink')}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,36 +1,16 @@
|
|||||||
import { FigureUpdateEvent, RoomSessionEvent, UserInfoDataParser, UserInfoEvent } from '@nitrots/nitro-renderer';
|
import { RoomSessionEvent } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback, useState } from 'react';
|
import { FC, useCallback, useState } from 'react';
|
||||||
import { GetConfiguration, GetConfigurationManager } from '../../api';
|
import { GetConfiguration, GetConfigurationManager } from '../../api';
|
||||||
import { LayoutAvatarImageView } from '../../common';
|
import { LayoutAvatarImageView } from '../../common';
|
||||||
import { UseMessageEventHook, UseRoomSessionManagerEvent } from '../../hooks';
|
import { UseRoomSessionManagerEvent, useSessionInfo } from '../../hooks';
|
||||||
import { WidgetSlotView } from './views/widgets/WidgetSlotView';
|
import { WidgetSlotView } from './views/widgets/WidgetSlotView';
|
||||||
|
|
||||||
|
const widgetSlotCount = 7;
|
||||||
|
|
||||||
export const HotelView: FC<{}> = props =>
|
export const HotelView: FC<{}> = props =>
|
||||||
{
|
{
|
||||||
const [ isVisible, setIsVisible ] = useState(true);
|
const [ isVisible, setIsVisible ] = useState(true);
|
||||||
const widgetSlotCount = 7;
|
const { userFigure = null } = useSessionInfo();
|
||||||
const [ userFigure, setUserFigure ] = useState<string>(null);
|
|
||||||
const [ userInfo, setUserInfo ] = useState<UserInfoDataParser>(null);
|
|
||||||
|
|
||||||
|
|
||||||
const onUserInfoEvent = useCallback((event: UserInfoEvent) =>
|
|
||||||
{
|
|
||||||
const parser = event.getParser();
|
|
||||||
|
|
||||||
setUserInfo(parser.userInfo);
|
|
||||||
setUserFigure(parser.userInfo.figure);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
UseMessageEventHook(UserInfoEvent, onUserInfoEvent);
|
|
||||||
|
|
||||||
const onUserFigureEvent = useCallback((event: FigureUpdateEvent) =>
|
|
||||||
{
|
|
||||||
const parser = event.getParser();
|
|
||||||
|
|
||||||
setUserFigure(parser.figure);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
UseMessageEventHook(FigureUpdateEvent, onUserFigureEvent);
|
|
||||||
|
|
||||||
|
|
||||||
const onRoomSessionEvent = useCallback((event: RoomSessionEvent) =>
|
const onRoomSessionEvent = useCallback((event: RoomSessionEvent) =>
|
||||||
{
|
{
|
||||||
@ -51,12 +31,12 @@ export const HotelView: FC<{}> = props =>
|
|||||||
if(!isVisible) return null;
|
if(!isVisible) return null;
|
||||||
|
|
||||||
const backgroundColor = GetConfiguration('hotelview')['images']['background.colour'];
|
const backgroundColor = GetConfiguration('hotelview')['images']['background.colour'];
|
||||||
const background = GetConfigurationManager().interpolate(GetConfiguration('hotelview')['images']['background']);
|
const background = GetConfigurationManager().interpolate(GetConfiguration('hotelview')['images']['background']);
|
||||||
const sun = GetConfigurationManager().interpolate(GetConfiguration('hotelview')['images']['sun']);
|
const sun = GetConfigurationManager().interpolate(GetConfiguration('hotelview')['images']['sun']);
|
||||||
const drape = GetConfigurationManager().interpolate(GetConfiguration('hotelview')['images']['drape']);
|
const drape = GetConfigurationManager().interpolate(GetConfiguration('hotelview')['images']['drape']);
|
||||||
const left = GetConfigurationManager().interpolate(GetConfiguration('hotelview')['images']['left']);
|
const left = GetConfigurationManager().interpolate(GetConfiguration('hotelview')['images']['left']);
|
||||||
const rightRepeat = GetConfigurationManager().interpolate(GetConfiguration('hotelview')['images']['right.repeat']);
|
const rightRepeat = GetConfigurationManager().interpolate(GetConfiguration('hotelview')['images']['right.repeat']);
|
||||||
const right = GetConfigurationManager().interpolate(GetConfiguration('hotelview')['images']['right']);
|
const right = GetConfigurationManager().interpolate(GetConfiguration('hotelview')['images']['right']);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="nitro-hotel-view" style={(backgroundColor && backgroundColor) ? { background: backgroundColor } : {}}>
|
<div className="nitro-hotel-view" style={(backgroundColor && backgroundColor) ? { background: backgroundColor } : {}}>
|
||||||
|
@ -8,7 +8,7 @@ export const InventoryBadgeView: FC<{}> = props =>
|
|||||||
{
|
{
|
||||||
const [ isVisible, setIsVisible ] = useState(false);
|
const [ isVisible, setIsVisible ] = useState(false);
|
||||||
const { badgeCodes = [], activeBadgeCodes = [], selectedBadgeCode = null, isWearingBadge = null, canWearBadges = null, toggleBadge = null, getBadgeId = null, activate = null, deactivate = null } = useInventoryBadges();
|
const { badgeCodes = [], activeBadgeCodes = [], selectedBadgeCode = null, isWearingBadge = null, canWearBadges = null, toggleBadge = null, getBadgeId = null, activate = null, deactivate = null } = useInventoryBadges();
|
||||||
const { getCount = null, resetCategory = null, isUnseen = null, removeUnseen = null } = useInventoryUnseenTracker();
|
const { isUnseen = null, removeUnseen = null } = useInventoryUnseenTracker();
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
|
@ -70,9 +70,9 @@ export const NavigatorSearchResultItemInfoView: FC<NavigatorSearchResultItemInfo
|
|||||||
<Flex gap={2} overflow="hidden">
|
<Flex gap={2} overflow="hidden">
|
||||||
<LayoutRoomThumbnailView roomId={roomData.roomId} customUrl={roomData.officialRoomPicRef} className="d-flex flex-column align-items-center justify-content-end mb-1">
|
<LayoutRoomThumbnailView roomId={roomData.roomId} customUrl={roomData.officialRoomPicRef} className="d-flex flex-column align-items-center justify-content-end mb-1">
|
||||||
{roomData.habboGroupId > 0 && (
|
{roomData.habboGroupId > 0 && (
|
||||||
<LayoutBadgeImageView badgeCode={roomData.groupBadgeCode} isGroup={true} className={"position-absolute top-0 start-0 m-1 "}/>)}
|
<LayoutBadgeImageView badgeCode={roomData.groupBadgeCode} isGroup={true} className={'position-absolute top-0 start-0 m-1 '}/>)}
|
||||||
{roomData.doorMode !== RoomDataParser.OPEN_STATE && (
|
{roomData.doorMode !== RoomDataParser.OPEN_STATE && (
|
||||||
<i className={"position-absolute end-0 mb-1 me-1 icon icon-navigator-room-" + (roomData.doorMode === RoomDataParser.DOORBELL_STATE ? "locked" : roomData.doorMode === RoomDataParser.PASSWORD_STATE ? "password" : roomData.doorMode === RoomDataParser.INVISIBLE_STATE ? "invisible" : "")}/> )}
|
<i className={'position-absolute end-0 mb-1 me-1 icon icon-navigator-room-' + (roomData.doorMode === RoomDataParser.DOORBELL_STATE ? 'locked' : roomData.doorMode === RoomDataParser.PASSWORD_STATE ? 'password' : roomData.doorMode === RoomDataParser.INVISIBLE_STATE ? 'invisible' : '')}/> )}
|
||||||
</LayoutRoomThumbnailView>
|
</LayoutRoomThumbnailView>
|
||||||
<Column gap={1}>
|
<Column gap={1}>
|
||||||
<Text bold truncate className="flex-grow-1" style={{ maxHeight: 13 }}>
|
<Text bold truncate className="flex-grow-1" style={{ maxHeight: 13 }}>
|
||||||
@ -80,7 +80,7 @@ export const NavigatorSearchResultItemInfoView: FC<NavigatorSearchResultItemInfo
|
|||||||
</Text>
|
</Text>
|
||||||
<Flex gap={1}>
|
<Flex gap={1}>
|
||||||
<Text italics variant="muted">
|
<Text italics variant="muted">
|
||||||
{LocalizeText("navigator.roomownercaption")}
|
{LocalizeText('navigator.roomownercaption')}
|
||||||
</Text>
|
</Text>
|
||||||
<UserProfileIconView
|
<UserProfileIconView
|
||||||
userId={roomData.ownerId}
|
userId={roomData.ownerId}
|
||||||
@ -90,7 +90,7 @@ export const NavigatorSearchResultItemInfoView: FC<NavigatorSearchResultItemInfo
|
|||||||
<Text className="flex-grow-1">
|
<Text className="flex-grow-1">
|
||||||
{roomData.description}
|
{roomData.description}
|
||||||
</Text>
|
</Text>
|
||||||
<Flex className={"badge p-1 position-absolute m-1 bottom-0 end-0 m-2 " + getUserCounterColor()} gap={1}>
|
<Flex className={'badge p-1 position-absolute m-1 bottom-0 end-0 m-2 ' + getUserCounterColor()} gap={1}>
|
||||||
<FontAwesomeIcon icon="user" />
|
<FontAwesomeIcon icon="user" />
|
||||||
{roomData.userCount}
|
{roomData.userCount}
|
||||||
</Flex>
|
</Flex>
|
||||||
|
@ -2,7 +2,7 @@ import { ActivityPointNotificationMessageEvent, FriendlyTime, HabboClubLevelEnum
|
|||||||
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import { CreateLinkEvent, GetConfiguration, LocalizeText, PlaySound, SendMessageComposer, SoundNames } from '../../api';
|
import { CreateLinkEvent, GetConfiguration, LocalizeText, PlaySound, SendMessageComposer, SoundNames } from '../../api';
|
||||||
import { Column, Flex, Grid, LayoutCurrencyIcon, Text } from '../../common';
|
import { Column, Flex, Grid, LayoutCurrencyIcon, Text } from '../../common';
|
||||||
import { HcCenterEvent, UserSettingsUIEvent } from '../../events';
|
import { UserSettingsUIEvent } from '../../events';
|
||||||
import { DispatchUiEvent, UseMessageEventHook } from '../../hooks';
|
import { DispatchUiEvent, UseMessageEventHook } from '../../hooks';
|
||||||
import { IPurse } from './common/IPurse';
|
import { IPurse } from './common/IPurse';
|
||||||
import { Purse } from './common/Purse';
|
import { Purse } from './common/Purse';
|
||||||
@ -179,7 +179,7 @@ export const PurseView: FC<{}> = props =>
|
|||||||
{ getCurrencyElements(0, 2) }
|
{ getCurrencyElements(0, 2) }
|
||||||
</Column>
|
</Column>
|
||||||
{ !hcDisabled &&
|
{ !hcDisabled &&
|
||||||
<Column center pointer size={ 4 } gap={ 1 } className="nitro-purse-subscription rounded" onClick={ event => DispatchUiEvent(new HcCenterEvent(HcCenterEvent.TOGGLE_HC_CENTER)) }>
|
<Column center pointer size={ 4 } gap={ 1 } className="nitro-purse-subscription rounded" onClick={ event => CreateLinkEvent('habboUI/open/hccenter') }>
|
||||||
<LayoutCurrencyIcon type="hc" />
|
<LayoutCurrencyIcon type="hc" />
|
||||||
<Text variant="white">{ getClubText }</Text>
|
<Text variant="white">{ getClubText }</Text>
|
||||||
</Column> }
|
</Column> }
|
||||||
|
@ -1,44 +1,24 @@
|
|||||||
import { Dispose, DropBounce, EaseOut, FigureUpdateEvent, JumpBy, Motions, NitroToolbarAnimateIconEvent, PerkAllowancesMessageEvent, PerkEnum, Queue, UserInfoDataParser, UserInfoEvent, Wait } from '@nitrots/nitro-renderer';
|
import { Dispose, DropBounce, EaseOut, JumpBy, Motions, NitroToolbarAnimateIconEvent, PerkAllowancesMessageEvent, PerkEnum, Queue, Wait } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback, useState } from 'react';
|
import { FC, useCallback, useState } from 'react';
|
||||||
import { CreateLinkEvent, GetSessionDataManager, MessengerIconState, OpenMessengerChat, VisitDesktop } from '../../api';
|
import { CreateLinkEvent, GetSessionDataManager, MessengerIconState, OpenMessengerChat, VisitDesktop } from '../../api';
|
||||||
import { Base, Flex, LayoutAvatarImageView, LayoutItemCountView, TransitionAnimation, TransitionAnimationTypes } from '../../common';
|
import { Base, Flex, LayoutAvatarImageView, LayoutItemCountView, TransitionAnimation, TransitionAnimationTypes } from '../../common';
|
||||||
import { AchievementsUIUnseenCountEvent, ModToolsEvent } from '../../events';
|
import { ModToolsEvent } from '../../events';
|
||||||
import { DispatchUiEvent, useFriends, useInventoryUnseenTracker, UseMessageEventHook, useMessenger, UseRoomEngineEvent, UseUiEvent } from '../../hooks';
|
import { DispatchUiEvent, useAchievements, useFriends, useInventoryUnseenTracker, UseMessageEventHook, useMessenger, UseRoomEngineEvent, useSessionInfo } from '../../hooks';
|
||||||
import { ToolbarMeView } from './ToolbarMeView';
|
import { ToolbarMeView } from './ToolbarMeView';
|
||||||
|
|
||||||
export const ToolbarView: FC<{ isInRoom: boolean }> = props =>
|
export const ToolbarView: FC<{ isInRoom: boolean }> = props =>
|
||||||
{
|
{
|
||||||
const { isInRoom } = props;
|
const { isInRoom } = props;
|
||||||
|
|
||||||
const [ userInfo, setUserInfo ] = useState<UserInfoDataParser>(null);
|
|
||||||
const [ userFigure, setUserFigure ] = useState<string>(null);
|
|
||||||
const [ isMeExpanded, setMeExpanded ] = useState(false);
|
const [ isMeExpanded, setMeExpanded ] = useState(false);
|
||||||
const [ useGuideTool, setUseGuideTool ] = useState(false);
|
const [ useGuideTool, setUseGuideTool ] = useState(false);
|
||||||
const [ unseenAchievementCount, setUnseenAchievementCount ] = useState(0);
|
const { userFigure = null } = useSessionInfo();
|
||||||
const { getFullCount = null } = useInventoryUnseenTracker();
|
const { getFullCount = 0 } = useInventoryUnseenTracker();
|
||||||
|
const { getTotalUnseen = 0 } = useAchievements();
|
||||||
const { requests = [] } = useFriends();
|
const { requests = [] } = useFriends();
|
||||||
const { iconState = MessengerIconState.HIDDEN } = useMessenger();
|
const { iconState = MessengerIconState.HIDDEN } = useMessenger();
|
||||||
const isMod = GetSessionDataManager().isModerator;
|
const isMod = GetSessionDataManager().isModerator;
|
||||||
|
|
||||||
const onUserInfoEvent = useCallback((event: UserInfoEvent) =>
|
|
||||||
{
|
|
||||||
const parser = event.getParser();
|
|
||||||
|
|
||||||
setUserInfo(parser.userInfo);
|
|
||||||
setUserFigure(parser.userInfo.figure);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
UseMessageEventHook(UserInfoEvent, onUserInfoEvent);
|
|
||||||
|
|
||||||
const onUserFigureEvent = useCallback((event: FigureUpdateEvent) =>
|
|
||||||
{
|
|
||||||
const parser = event.getParser();
|
|
||||||
|
|
||||||
setUserFigure(parser.figure);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
UseMessageEventHook(FigureUpdateEvent, onUserFigureEvent);
|
|
||||||
|
|
||||||
const onPerkAllowancesMessageEvent = useCallback((event: PerkAllowancesMessageEvent) =>
|
const onPerkAllowancesMessageEvent = useCallback((event: PerkAllowancesMessageEvent) =>
|
||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
@ -48,13 +28,6 @@ export const ToolbarView: FC<{ isInRoom: boolean }> = props =>
|
|||||||
|
|
||||||
UseMessageEventHook(PerkAllowancesMessageEvent, onPerkAllowancesMessageEvent);
|
UseMessageEventHook(PerkAllowancesMessageEvent, onPerkAllowancesMessageEvent);
|
||||||
|
|
||||||
const onAchievementsUIUnseenCountEvent = useCallback((event: AchievementsUIUnseenCountEvent) =>
|
|
||||||
{
|
|
||||||
setUnseenAchievementCount(event.count);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
UseUiEvent(AchievementsUIUnseenCountEvent.UNSEEN_COUNT, onAchievementsUIUnseenCountEvent);
|
|
||||||
|
|
||||||
const animationIconToToolbar = useCallback((iconName: string, image: HTMLImageElement, x: number, y: number) =>
|
const animationIconToToolbar = useCallback((iconName: string, image: HTMLImageElement, x: number, y: number) =>
|
||||||
{
|
{
|
||||||
const target = (document.body.getElementsByClassName(iconName)[0] as HTMLElement);
|
const target = (document.body.getElementsByClassName(iconName)[0] as HTMLElement);
|
||||||
@ -96,20 +69,18 @@ export const ToolbarView: FC<{ isInRoom: boolean }> = props =>
|
|||||||
|
|
||||||
UseRoomEngineEvent(NitroToolbarAnimateIconEvent.ANIMATE_ICON, onNitroToolbarAnimateIconEvent);
|
UseRoomEngineEvent(NitroToolbarAnimateIconEvent.ANIMATE_ICON, onNitroToolbarAnimateIconEvent);
|
||||||
|
|
||||||
const unseenInventoryCount = getFullCount();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TransitionAnimation type={ TransitionAnimationTypes.FADE_IN } inProp={ isMeExpanded } timeout={ 300 }>
|
<TransitionAnimation type={ TransitionAnimationTypes.FADE_IN } inProp={ isMeExpanded } timeout={ 300 }>
|
||||||
<ToolbarMeView useGuideTool={ useGuideTool } unseenAchievementCount={ unseenAchievementCount } setMeExpanded={ setMeExpanded } />
|
<ToolbarMeView useGuideTool={ useGuideTool } unseenAchievementCount={ getTotalUnseen } setMeExpanded={ setMeExpanded } />
|
||||||
</TransitionAnimation>
|
</TransitionAnimation>
|
||||||
<Flex alignItems="center" justifyContent="between" gap={ 2 } className="nitro-toolbar py-1 px-3">
|
<Flex alignItems="center" justifyContent="between" gap={ 2 } className="nitro-toolbar py-1 px-3">
|
||||||
<Flex gap={ 2 } alignItems="center">
|
<Flex gap={ 2 } alignItems="center">
|
||||||
<Flex alignItems="center" gap={ 2 }>
|
<Flex alignItems="center" gap={ 2 }>
|
||||||
<Flex center pointer className={ 'navigation-item item-avatar ' + (isMeExpanded ? 'active ' : '') } onClick={ event => setMeExpanded(!isMeExpanded) }>
|
<Flex center pointer className={ 'navigation-item item-avatar ' + (isMeExpanded ? 'active ' : '') } onClick={ event => setMeExpanded(!isMeExpanded) }>
|
||||||
<LayoutAvatarImageView figure={ userFigure } direction={ 2 } />
|
<LayoutAvatarImageView figure={ userFigure } direction={ 2 } />
|
||||||
{ (unseenAchievementCount > 0) &&
|
{ (getTotalUnseen > 0) &&
|
||||||
<LayoutItemCountView count={ unseenAchievementCount } /> }
|
<LayoutItemCountView count={ getTotalUnseen } /> }
|
||||||
</Flex>
|
</Flex>
|
||||||
{ isInRoom &&
|
{ isInRoom &&
|
||||||
<Base pointer className="navigation-item icon icon-habbo" onClick={ event => VisitDesktop() } /> }
|
<Base pointer className="navigation-item icon icon-habbo" onClick={ event => VisitDesktop() } /> }
|
||||||
@ -118,8 +89,8 @@ export const ToolbarView: FC<{ isInRoom: boolean }> = props =>
|
|||||||
<Base pointer className="navigation-item icon icon-rooms" onClick={ event => CreateLinkEvent('navigator/toggle') } />
|
<Base pointer className="navigation-item icon icon-rooms" onClick={ event => CreateLinkEvent('navigator/toggle') } />
|
||||||
<Base pointer className="navigation-item icon icon-catalog" onClick={ event => CreateLinkEvent('catalog/toggle') } />
|
<Base pointer className="navigation-item icon icon-catalog" onClick={ event => CreateLinkEvent('catalog/toggle') } />
|
||||||
<Base pointer className="navigation-item icon icon-inventory" onClick={ event => CreateLinkEvent('inventory/toggle') }>
|
<Base pointer className="navigation-item icon icon-inventory" onClick={ event => CreateLinkEvent('inventory/toggle') }>
|
||||||
{ (unseenInventoryCount > 0) &&
|
{ (getFullCount > 0) &&
|
||||||
<LayoutItemCountView count={ unseenInventoryCount } /> }
|
<LayoutItemCountView count={ getFullCount } /> }
|
||||||
</Base>
|
</Base>
|
||||||
{ isInRoom &&
|
{ isInRoom &&
|
||||||
<Base pointer className="navigation-item icon icon-camera" onClick={ event => CreateLinkEvent('camera/toggle') } /> }
|
<Base pointer className="navigation-item icon icon-camera" onClick={ event => CreateLinkEvent('camera/toggle') } /> }
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
import { NitroEvent } from '@nitrots/nitro-renderer';
|
|
||||||
|
|
||||||
export class AchievementsUIUnseenCountEvent extends NitroEvent
|
|
||||||
{
|
|
||||||
public static UNSEEN_COUNT: string = 'AUUCE_UNSEEN_COUNT';
|
|
||||||
|
|
||||||
private _count: number;
|
|
||||||
|
|
||||||
constructor(count: number)
|
|
||||||
{
|
|
||||||
super(AchievementsUIUnseenCountEvent.UNSEEN_COUNT);
|
|
||||||
|
|
||||||
this._count = count;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get count(): number
|
|
||||||
{
|
|
||||||
return this._count;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
export * from './AchievementsUIUnseenCountEvent';
|
|
@ -1,48 +0,0 @@
|
|||||||
import { NitroEvent } from '@nitrots/nitro-renderer';
|
|
||||||
|
|
||||||
export class FriendEnteredRoomEvent extends NitroEvent
|
|
||||||
{
|
|
||||||
public static ENTERED: string = 'FERE_ENTERED';
|
|
||||||
|
|
||||||
private _roomIndex: number;
|
|
||||||
private _category: number;
|
|
||||||
private _id: number;
|
|
||||||
private _name: string;
|
|
||||||
private _userType: number;
|
|
||||||
|
|
||||||
constructor(roomIndex: number, category: number, id: number, name: string, userType: number)
|
|
||||||
{
|
|
||||||
super(FriendEnteredRoomEvent.ENTERED);
|
|
||||||
|
|
||||||
this._roomIndex = roomIndex;
|
|
||||||
this._category = category;
|
|
||||||
this._id = id;
|
|
||||||
this._name = name;
|
|
||||||
this._userType = userType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get roomIndex(): number
|
|
||||||
{
|
|
||||||
return this._roomIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get category(): number
|
|
||||||
{
|
|
||||||
return this._category;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get id(): number
|
|
||||||
{
|
|
||||||
return this._id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get name(): string
|
|
||||||
{
|
|
||||||
return this._name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get userType(): number
|
|
||||||
{
|
|
||||||
return this._userType;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
export * from './FriendEnteredRoomEvent';
|
|
@ -1,6 +0,0 @@
|
|||||||
import { NitroEvent } from '@nitrots/nitro-renderer';
|
|
||||||
|
|
||||||
export class HcCenterEvent extends NitroEvent
|
|
||||||
{
|
|
||||||
public static TOGGLE_HC_CENTER: string = 'HCC_TOGGLE';
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
export * from './HcCenterEvent';
|
|
@ -1,11 +1,7 @@
|
|||||||
export * from './achievements';
|
|
||||||
export * from './catalog';
|
export * from './catalog';
|
||||||
export * from './floorplan-editor';
|
export * from './floorplan-editor';
|
||||||
export * from './friends';
|
|
||||||
export * from './guide-tool';
|
export * from './guide-tool';
|
||||||
export * from './hc-center';
|
|
||||||
export * from './help';
|
export * from './help';
|
||||||
export * from './inventory';
|
|
||||||
export * from './mod-tools';
|
export * from './mod-tools';
|
||||||
export * from './notification-center';
|
export * from './notification-center';
|
||||||
export * from './room-widgets';
|
export * from './room-widgets';
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
import { NitroEvent } from '@nitrots/nitro-renderer';
|
|
||||||
|
|
||||||
export class InventoryEvent extends NitroEvent
|
|
||||||
{
|
|
||||||
public static SHOW_INVENTORY: string = 'IE_SHOW_INVENTORY';
|
|
||||||
public static HIDE_INVENTORY: string = 'IE_HIDE_INVENTORY';
|
|
||||||
public static TOGGLE_INVENTORY: string = 'IE_TOGGLE_INVENTORY';
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
import { InventoryEvent } from './InventoryEvent';
|
|
||||||
|
|
||||||
export class InventoryTradeRequestEvent extends InventoryEvent
|
|
||||||
{
|
|
||||||
public static REQUEST_TRADE: string = 'ITSE_REQUEST_TRADE';
|
|
||||||
|
|
||||||
private _objectId: number;
|
|
||||||
private _username: string;
|
|
||||||
|
|
||||||
constructor(objectId: number, username: string)
|
|
||||||
{
|
|
||||||
super(InventoryTradeRequestEvent.REQUEST_TRADE);
|
|
||||||
|
|
||||||
this._objectId = objectId;
|
|
||||||
this._username = username;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get objectId(): number
|
|
||||||
{
|
|
||||||
return this._objectId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get username(): string
|
|
||||||
{
|
|
||||||
return this._username;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
import { TradeUserData } from '../../api';
|
|
||||||
import { InventoryEvent } from './InventoryEvent';
|
|
||||||
|
|
||||||
export class InventoryTradeStartEvent extends InventoryEvent
|
|
||||||
{
|
|
||||||
public static START_TRADE: string = 'ITSE_START_TRADE';
|
|
||||||
|
|
||||||
private _ownUserTradeData: TradeUserData;
|
|
||||||
private _otherUserTradeData: TradeUserData;
|
|
||||||
|
|
||||||
constructor(ownUserTradeData: TradeUserData, otherUserTradeData: TradeUserData)
|
|
||||||
{
|
|
||||||
super(InventoryTradeStartEvent.START_TRADE);
|
|
||||||
|
|
||||||
this._ownUserTradeData = ownUserTradeData;
|
|
||||||
this._otherUserTradeData = otherUserTradeData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get ownUserTradeData(): TradeUserData
|
|
||||||
{
|
|
||||||
return this._ownUserTradeData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get otherUserTradeData(): TradeUserData
|
|
||||||
{
|
|
||||||
return this._otherUserTradeData;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
export * from './InventoryEvent';
|
|
||||||
export * from './InventoryTradeRequestEvent';
|
|
||||||
export * from './InventoryTradeStartEvent';
|
|
1
src/hooks/achievements/index.ts
Normal file
1
src/hooks/achievements/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './useAchievements';
|
169
src/hooks/achievements/useAchievements.ts
Normal file
169
src/hooks/achievements/useAchievements.ts
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
import { AchievementData, AchievementEvent, AchievementsEvent, AchievementsScoreEvent, RequestAchievementsMessageComposer } from '@nitrots/nitro-renderer';
|
||||||
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
|
import { AchievementCategory, CloneObject, GetAchievementCategoryTotalUnseen, GetAchievementIsIgnored, SendMessageComposer } from '../../api';
|
||||||
|
import { UseMessageEventHook } from '../messages';
|
||||||
|
|
||||||
|
const useAchievementsState = () =>
|
||||||
|
{
|
||||||
|
const [ needsUpdate, setNeedsUpdate ] = useState<boolean>(true);
|
||||||
|
const [ achievementCategories, setAchievementCategories ] = useState<AchievementCategory[]>([]);
|
||||||
|
const [ selectedCategoryCode, setSelectedCategoryCode ] = useState<string>(null);
|
||||||
|
const [ selectedAchievementId, setSelectedAchievementId ] = useState<number>(-1);
|
||||||
|
const [ achievementScore, setAchievementScore ] = useState<number>(0);
|
||||||
|
|
||||||
|
const getTotalUnseen = useMemo(() =>
|
||||||
|
{
|
||||||
|
let unseen = 0;
|
||||||
|
|
||||||
|
achievementCategories.forEach(category => unseen += GetAchievementCategoryTotalUnseen(category));
|
||||||
|
|
||||||
|
return unseen;
|
||||||
|
}, [ achievementCategories ]);
|
||||||
|
|
||||||
|
const getProgress = useMemo(() =>
|
||||||
|
{
|
||||||
|
let progress = 0;
|
||||||
|
|
||||||
|
achievementCategories.forEach(category => (progress += category.getProgress()));
|
||||||
|
|
||||||
|
return progress;
|
||||||
|
}, [ achievementCategories ]);
|
||||||
|
|
||||||
|
const getMaxProgress = useMemo(() =>
|
||||||
|
{
|
||||||
|
let progress = 0;
|
||||||
|
|
||||||
|
achievementCategories.forEach(category => (progress += category.getMaxProgress()));
|
||||||
|
|
||||||
|
return progress;
|
||||||
|
}, [ achievementCategories ]);
|
||||||
|
|
||||||
|
const scaledProgressPercent = useMemo(() =>
|
||||||
|
{
|
||||||
|
return ~~((((getProgress - 0) * (100 - 0)) / (getMaxProgress - 0)) + 0);
|
||||||
|
}, [ getProgress, getMaxProgress ]);
|
||||||
|
|
||||||
|
const setAchievementSeen = useCallback((categoryCode: string, achievementId: number) =>
|
||||||
|
{
|
||||||
|
setAchievementCategories(prevValue =>
|
||||||
|
{
|
||||||
|
const newValue = [ ...prevValue ];
|
||||||
|
|
||||||
|
for(const category of newValue)
|
||||||
|
{
|
||||||
|
if(category.code !== categoryCode) continue;
|
||||||
|
|
||||||
|
for(const achievement of category.achievements)
|
||||||
|
{
|
||||||
|
if(achievement.achievementId !== achievementId) continue;
|
||||||
|
|
||||||
|
achievement.unseen = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return newValue;
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const onAchievementEvent = useCallback((event: AchievementEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
const achievement = parser.achievement;
|
||||||
|
|
||||||
|
setAchievementCategories(prevValue =>
|
||||||
|
{
|
||||||
|
const newValue = [ ...prevValue ];
|
||||||
|
const categoryIndex = newValue.findIndex(existing => (existing.code === achievement.category));
|
||||||
|
|
||||||
|
if(categoryIndex === -1)
|
||||||
|
{
|
||||||
|
const category = new AchievementCategory(achievement.category);
|
||||||
|
|
||||||
|
category.achievements.push(achievement);
|
||||||
|
|
||||||
|
newValue.push(category);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const category = CloneObject(newValue[categoryIndex]);
|
||||||
|
const newAchievements = [ ...category.achievements ];
|
||||||
|
const achievementIndex = newAchievements.findIndex(existing => (existing.achievementId === achievement.achievementId));
|
||||||
|
let previousAchievement: AchievementData = null;
|
||||||
|
|
||||||
|
if(achievementIndex === -1)
|
||||||
|
{
|
||||||
|
newAchievements.push(achievement);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
previousAchievement = newAchievements[achievementIndex];
|
||||||
|
|
||||||
|
newAchievements[achievementIndex] = achievement;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!GetAchievementIsIgnored(achievement))
|
||||||
|
{
|
||||||
|
achievement.unseen++;
|
||||||
|
|
||||||
|
if(previousAchievement) achievement.unseen += previousAchievement.unseen;
|
||||||
|
}
|
||||||
|
|
||||||
|
category.achievements = newAchievements;
|
||||||
|
|
||||||
|
newValue[categoryIndex] = category;
|
||||||
|
}
|
||||||
|
|
||||||
|
return newValue;
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
UseMessageEventHook(AchievementEvent, onAchievementEvent);
|
||||||
|
|
||||||
|
const onAchievementsEvent = useCallback((event: AchievementsEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
const categories: AchievementCategory[] = [];
|
||||||
|
|
||||||
|
for(const achievement of parser.achievements)
|
||||||
|
{
|
||||||
|
const categoryName = achievement.category;
|
||||||
|
|
||||||
|
let existing = categories.find(category => (category.code === categoryName));
|
||||||
|
|
||||||
|
if(!existing)
|
||||||
|
{
|
||||||
|
existing = new AchievementCategory(categoryName);
|
||||||
|
|
||||||
|
categories.push(existing);
|
||||||
|
}
|
||||||
|
|
||||||
|
existing.achievements.push(achievement);
|
||||||
|
}
|
||||||
|
|
||||||
|
setAchievementCategories(categories);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
UseMessageEventHook(AchievementsEvent, onAchievementsEvent);
|
||||||
|
|
||||||
|
const onAchievementsScoreEvent = useCallback((event: AchievementsScoreEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
setAchievementScore(parser.score);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
UseMessageEventHook(AchievementsScoreEvent, onAchievementsScoreEvent);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
if(!needsUpdate) return;
|
||||||
|
|
||||||
|
SendMessageComposer(new RequestAchievementsMessageComposer());
|
||||||
|
|
||||||
|
setNeedsUpdate(false);
|
||||||
|
}, [ needsUpdate ]);
|
||||||
|
|
||||||
|
return { achievementCategories, selectedCategoryCode, setSelectedCategoryCode, selectedAchievementId, setSelectedAchievementId, achievementScore, getTotalUnseen, getProgress, getMaxProgress, scaledProgressPercent, setAchievementSeen };
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useAchievements = useAchievementsState;
|
@ -1,3 +1,4 @@
|
|||||||
|
export * from './achievements';
|
||||||
export * from './events';
|
export * from './events';
|
||||||
export * from './events/core';
|
export * from './events/core';
|
||||||
export * from './events/nitro';
|
export * from './events/nitro';
|
||||||
@ -6,5 +7,6 @@ export * from './friends';
|
|||||||
export * from './inventory';
|
export * from './inventory';
|
||||||
export * from './messages';
|
export * from './messages';
|
||||||
export * from './navigator';
|
export * from './navigator';
|
||||||
|
export * from './session';
|
||||||
export * from './UseMountEffect';
|
export * from './UseMountEffect';
|
||||||
export * from './useSharedVisibility';
|
export * from './useSharedVisibility';
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
import { AdvancedMap, TradingAcceptComposer, TradingAcceptEvent, TradingCancelComposer, TradingCloseComposer, TradingCloseEvent, TradingCloseParser, TradingCompletedEvent, TradingConfirmationComposer, TradingConfirmationEvent, TradingListItemEvent, TradingListItemRemoveComposer, TradingNotOpenEvent, TradingOpenComposer, TradingOpenEvent, TradingOpenFailedEvent, TradingOtherNotAllowedEvent, TradingUnacceptComposer, TradingYouAreNotAllowedEvent } from '@nitrots/nitro-renderer';
|
import { AdvancedMap, TradingAcceptComposer, TradingAcceptEvent, TradingCancelComposer, TradingCloseComposer, TradingCloseEvent, TradingCloseParser, TradingCompletedEvent, TradingConfirmationComposer, TradingConfirmationEvent, TradingListItemEvent, TradingListItemRemoveComposer, TradingNotOpenEvent, TradingOpenEvent, TradingOpenFailedEvent, TradingOtherNotAllowedEvent, TradingUnacceptComposer, TradingYouAreNotAllowedEvent } from '@nitrots/nitro-renderer';
|
||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
import { useBetween } from 'use-between';
|
import { useBetween } from 'use-between';
|
||||||
import { useInventoryFurni } from '.';
|
import { useInventoryFurni } from '.';
|
||||||
import { UseMessageEventHook } from '..';
|
import { UseMessageEventHook } from '..';
|
||||||
import { CloneObject, GetRoomSession, GetSessionDataManager, GroupItem, LocalizeText, NotificationUtilities, parseTradeItems, SendMessageComposer, TradeState, TradeUserData, TradingNotificationMessage, TradingNotificationType } from '../../api';
|
import { CloneObject, GetRoomSession, GetSessionDataManager, GroupItem, LocalizeText, NotificationUtilities, parseTradeItems, SendMessageComposer, TradeState, TradeUserData, TradingNotificationMessage, TradingNotificationType } from '../../api';
|
||||||
import { InventoryTradeRequestEvent } from '../../events';
|
|
||||||
import { UseUiEvent } from '../events';
|
|
||||||
|
|
||||||
const useInventoryTradeState = () =>
|
const useInventoryTradeState = () =>
|
||||||
{
|
{
|
||||||
@ -66,20 +64,6 @@ const useInventoryTradeState = () =>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const onInventoryTradeRequestEvent = useCallback((event: InventoryTradeRequestEvent) =>
|
|
||||||
{
|
|
||||||
switch(event.type)
|
|
||||||
{
|
|
||||||
case InventoryTradeRequestEvent.REQUEST_TRADE: {
|
|
||||||
const tradeEvent = (event as InventoryTradeRequestEvent);
|
|
||||||
|
|
||||||
SendMessageComposer(new TradingOpenComposer(tradeEvent.objectId));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
UseUiEvent(InventoryTradeRequestEvent.REQUEST_TRADE, onInventoryTradeRequestEvent);
|
|
||||||
|
|
||||||
const onTradingAcceptEvent = useCallback((event: TradingAcceptEvent) =>
|
const onTradingAcceptEvent = useCallback((event: TradingAcceptEvent) =>
|
||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { UnseenItemsEvent, UnseenResetCategoryComposer, UnseenResetItemsComposer } from '@nitrots/nitro-renderer';
|
import { UnseenItemsEvent, UnseenResetCategoryComposer, UnseenResetItemsComposer } from '@nitrots/nitro-renderer';
|
||||||
import { useCallback, useState } from 'react';
|
import { useCallback, useMemo, useState } from 'react';
|
||||||
import { useBetween } from 'use-between';
|
import { useBetween } from 'use-between';
|
||||||
import { UseMessageEventHook } from '..';
|
import { UseMessageEventHook } from '..';
|
||||||
import { SendMessageComposer } from '../../api';
|
import { SendMessageComposer } from '../../api';
|
||||||
@ -10,17 +10,17 @@ const sendResetItemsMessage = (category: number, itemIds: number[]) => SendMessa
|
|||||||
const useInventoryUnseenTrackerState = () =>
|
const useInventoryUnseenTrackerState = () =>
|
||||||
{
|
{
|
||||||
const [ unseenItems, setUnseenItems ] = useState<Map<number, number[]>>(new Map());
|
const [ unseenItems, setUnseenItems ] = useState<Map<number, number[]>>(new Map());
|
||||||
const getIds = (category: number) => unseenItems.get(category);
|
|
||||||
const getCount = (category: number) => (unseenItems.get(category)?.length || 0);
|
|
||||||
|
|
||||||
const getFullCount = () =>
|
const getCount = useCallback((category: number) => (unseenItems.get(category)?.length || 0), [ unseenItems ]);
|
||||||
|
|
||||||
|
const getFullCount = useMemo(() =>
|
||||||
{
|
{
|
||||||
let count = 0;
|
let count = 0;
|
||||||
|
|
||||||
for(const key of unseenItems.keys()) count += getCount(key);
|
for(const key of unseenItems.keys()) count += getCount(key);
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}, [ unseenItems, getCount ]);
|
||||||
|
|
||||||
const resetCategory = useCallback((category: number) =>
|
const resetCategory = useCallback((category: number) =>
|
||||||
{
|
{
|
||||||
@ -128,7 +128,7 @@ const useInventoryUnseenTrackerState = () =>
|
|||||||
|
|
||||||
UseMessageEventHook(UnseenItemsEvent, onUnseenItemsEvent);
|
UseMessageEventHook(UnseenItemsEvent, onUnseenItemsEvent);
|
||||||
|
|
||||||
return { getIds, getCount, getFullCount, resetCategory, resetItems, isUnseen, removeUnseen };
|
return { getCount, getFullCount, resetCategory, resetItems, isUnseen, removeUnseen };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useInventoryUnseenTracker = () => useBetween(useInventoryUnseenTrackerState);
|
export const useInventoryUnseenTracker = () => useBetween(useInventoryUnseenTrackerState);
|
||||||
|
1
src/hooks/session/index.ts
Normal file
1
src/hooks/session/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './useSessionInfo';
|
33
src/hooks/session/useSessionInfo.ts
Normal file
33
src/hooks/session/useSessionInfo.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import { FigureUpdateEvent, UserInfoDataParser, UserInfoEvent } from '@nitrots/nitro-renderer';
|
||||||
|
import { useCallback, useState } from 'react';
|
||||||
|
import { useBetween } from 'use-between';
|
||||||
|
import { UseMessageEventHook } from '../messages';
|
||||||
|
|
||||||
|
const useSessionInfoState = () =>
|
||||||
|
{
|
||||||
|
const [ userInfo, setUserInfo ] = useState<UserInfoDataParser>(null);
|
||||||
|
const [ userFigure, setUserFigure ] = useState<string>(null);
|
||||||
|
|
||||||
|
const onUserInfoEvent = useCallback((event: UserInfoEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
setUserInfo(parser.userInfo);
|
||||||
|
setUserFigure(parser.userInfo.figure);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
UseMessageEventHook(UserInfoEvent, onUserInfoEvent);
|
||||||
|
|
||||||
|
const onUserFigureEvent = useCallback((event: FigureUpdateEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
setUserFigure(parser.figure);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
UseMessageEventHook(FigureUpdateEvent, onUserFigureEvent);
|
||||||
|
|
||||||
|
return { userInfo, userFigure };
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useSessionInfo = () => useBetween(useSessionInfoState);
|
Loading…
Reference in New Issue
Block a user