2021-08-26 05:06:42 +02:00
|
|
|
import { GetCatalogIndexComposer, GetCatalogPageComposer, GetGiftWrappingConfigurationComposer, ILinkEventTracker, INodeData, RoomPreviewer } from '@nitrots/nitro-renderer';
|
2021-05-05 09:14:54 +02:00
|
|
|
import { FC, useCallback, useEffect, useReducer, useState } from 'react';
|
2021-08-17 05:38:07 +02:00
|
|
|
import { AddEventLinkTracker, GetRoomEngine, LocalizeText, RemoveLinkEventTracker } from '../../api';
|
2021-11-26 06:16:00 +01:00
|
|
|
import { CREDITS, PlaySound } from '../../api/utils/PlaySound';
|
2021-04-22 05:26:30 +02:00
|
|
|
import { CatalogEvent } from '../../events';
|
|
|
|
import { useUiEvent } from '../../hooks/events/ui/ui-event';
|
2021-05-05 09:14:54 +02:00
|
|
|
import { SendMessageHook } from '../../hooks/messages/message-event';
|
2021-09-30 04:31:31 +02:00
|
|
|
import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView, NitroLayoutGrid, NitroLayoutGridColumn } from '../../layout';
|
2021-04-22 05:26:30 +02:00
|
|
|
import { CatalogMessageHandler } from './CatalogMessageHandler';
|
2021-05-05 09:14:54 +02:00
|
|
|
import { CatalogMode, CatalogViewProps } from './CatalogView.types';
|
2021-07-28 02:01:37 +02:00
|
|
|
import { BuildCatalogPageTree } from './common/CatalogUtilities';
|
2021-05-05 09:14:54 +02:00
|
|
|
import { CatalogContextProvider } from './context/CatalogContext';
|
2021-07-28 02:01:37 +02:00
|
|
|
import { CatalogReducer, initialCatalog } from './reducers/CatalogReducer';
|
2021-09-17 08:39:58 +02:00
|
|
|
import { CatalogGiftView } from './views/gift/CatalogGiftView';
|
2021-07-29 08:03:30 +02:00
|
|
|
import { ACTIVE_PAGES, CatalogNavigationView } from './views/navigation/CatalogNavigationView';
|
2021-05-05 09:14:54 +02:00
|
|
|
import { CatalogPageView } from './views/page/CatalogPageView';
|
2021-04-22 05:26:30 +02:00
|
|
|
|
|
|
|
export const CatalogView: FC<CatalogViewProps> = props =>
|
|
|
|
{
|
|
|
|
const [ isVisible, setIsVisible ] = useState(false);
|
2021-05-10 19:11:16 +02:00
|
|
|
const [ roomPreviewer, setRoomPreviewer ] = useState<RoomPreviewer>(null);
|
2021-07-29 02:13:40 +02:00
|
|
|
const [ pendingPageLookup, setPendingPageLookup ] = useState<{ value: string, isOffer: boolean }>(null);
|
2021-08-26 05:06:42 +02:00
|
|
|
const [ pendingTree, setPendingTree ] = useState<INodeData[]>(null);
|
|
|
|
const [ pendingOpenTree, setPendingOpenTree ] = useState<INodeData[]>(null);
|
2021-05-05 09:14:54 +02:00
|
|
|
const [ catalogState, dispatchCatalogState ] = useReducer(CatalogReducer, initialCatalog);
|
2021-08-26 05:06:42 +02:00
|
|
|
const [ currentTab, setCurrentTab ] = useState<INodeData>(null);
|
2021-08-16 08:00:31 +02:00
|
|
|
const { root = null, pageParser = null, activeOffer = null, searchResult = null } = catalogState;
|
2021-04-22 05:26:30 +02:00
|
|
|
|
2021-07-29 08:03:30 +02:00
|
|
|
const saveActivePages = useCallback(() =>
|
|
|
|
{
|
|
|
|
setPendingOpenTree(ACTIVE_PAGES.slice());
|
|
|
|
}, []);
|
|
|
|
|
2021-04-22 05:26:30 +02:00
|
|
|
const onCatalogEvent = useCallback((event: CatalogEvent) =>
|
|
|
|
{
|
2021-07-29 08:03:30 +02:00
|
|
|
let save = false;
|
|
|
|
|
2021-04-22 05:26:30 +02:00
|
|
|
switch(event.type)
|
|
|
|
{
|
|
|
|
case CatalogEvent.SHOW_CATALOG:
|
|
|
|
setIsVisible(true);
|
|
|
|
return;
|
2021-05-10 19:11:16 +02:00
|
|
|
case CatalogEvent.HIDE_CATALOG:
|
2021-07-29 08:03:30 +02:00
|
|
|
save = true;
|
2021-05-10 19:11:16 +02:00
|
|
|
setIsVisible(false);
|
|
|
|
return;
|
2021-04-22 05:26:30 +02:00
|
|
|
case CatalogEvent.TOGGLE_CATALOG:
|
2021-07-29 08:03:30 +02:00
|
|
|
save = true;
|
2021-04-22 05:26:30 +02:00
|
|
|
setIsVisible(value => !value);
|
|
|
|
return;
|
2021-11-26 04:32:51 +01:00
|
|
|
case CatalogEvent.PURCHASE_SUCCESS:
|
2021-11-26 06:16:00 +01:00
|
|
|
PlaySound(CREDITS);
|
2021-11-26 04:32:51 +01:00
|
|
|
return;
|
2021-04-22 05:26:30 +02:00
|
|
|
}
|
2021-07-29 08:03:30 +02:00
|
|
|
|
|
|
|
if(save) saveActivePages();
|
|
|
|
}, [ saveActivePages ]);
|
2021-04-22 05:26:30 +02:00
|
|
|
|
|
|
|
useUiEvent(CatalogEvent.SHOW_CATALOG, onCatalogEvent);
|
2021-05-10 19:11:16 +02:00
|
|
|
useUiEvent(CatalogEvent.HIDE_CATALOG, onCatalogEvent);
|
2021-04-22 05:26:30 +02:00
|
|
|
useUiEvent(CatalogEvent.TOGGLE_CATALOG, onCatalogEvent);
|
2021-06-12 04:53:56 +02:00
|
|
|
useUiEvent(CatalogEvent.CATALOG_RESET, onCatalogEvent);
|
2021-11-26 04:32:51 +01:00
|
|
|
useUiEvent(CatalogEvent.PURCHASE_SUCCESS, onCatalogEvent);
|
2021-04-22 05:26:30 +02:00
|
|
|
|
2021-07-23 07:04:12 +02:00
|
|
|
const linkReceived = useCallback((url: string) =>
|
|
|
|
{
|
|
|
|
const parts = url.split('/');
|
|
|
|
|
|
|
|
if(parts.length < 2) return;
|
|
|
|
|
|
|
|
switch(parts[1])
|
|
|
|
{
|
|
|
|
case 'open':
|
|
|
|
if(parts.length > 2)
|
|
|
|
{
|
2021-07-29 02:13:40 +02:00
|
|
|
if(parts.length === 4)
|
|
|
|
{
|
|
|
|
switch(parts[2])
|
|
|
|
{
|
|
|
|
case 'offerId':
|
|
|
|
setPendingPageLookup({ value: parts[3], isOffer: true });
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
setPendingPageLookup({ value: parts[2], isOffer: false });
|
2021-07-23 07:04:12 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
setIsVisible(true);
|
|
|
|
}
|
2021-07-29 02:13:40 +02:00
|
|
|
|
2021-07-23 07:04:12 +02:00
|
|
|
return;
|
|
|
|
}
|
2021-07-25 07:33:30 +02:00
|
|
|
}, []);
|
2021-07-23 07:04:12 +02:00
|
|
|
|
|
|
|
useEffect(() =>
|
|
|
|
{
|
|
|
|
const linkTracker: ILinkEventTracker = {
|
|
|
|
linkReceived,
|
|
|
|
eventUrlPrefix: 'catalog/'
|
|
|
|
};
|
|
|
|
|
|
|
|
AddEventLinkTracker(linkTracker);
|
|
|
|
|
|
|
|
return () => RemoveLinkEventTracker(linkTracker);
|
2021-07-29 08:03:30 +02:00
|
|
|
}, [ linkReceived ]);
|
2021-07-23 07:04:12 +02:00
|
|
|
|
2021-05-05 09:14:54 +02:00
|
|
|
useEffect(() =>
|
2021-04-22 05:26:30 +02:00
|
|
|
{
|
2021-07-28 04:41:51 +02:00
|
|
|
const loadCatalog = (((pendingPageLookup !== null) && !catalogState.root) || (isVisible && !catalogState.root));
|
2021-07-23 19:23:31 +02:00
|
|
|
|
|
|
|
if(loadCatalog)
|
2021-05-05 09:14:54 +02:00
|
|
|
{
|
2021-08-26 04:29:02 +02:00
|
|
|
SendMessageHook(new GetCatalogIndexComposer(CatalogMode.MODE_NORMAL));
|
|
|
|
SendMessageHook(new GetGiftWrappingConfigurationComposer());
|
2021-07-28 02:01:37 +02:00
|
|
|
|
|
|
|
return;
|
2021-05-05 09:14:54 +02:00
|
|
|
}
|
2021-07-23 07:04:12 +02:00
|
|
|
|
2021-07-23 19:23:31 +02:00
|
|
|
if(catalogState.root)
|
|
|
|
{
|
2021-07-28 04:41:51 +02:00
|
|
|
if(!isVisible && (pendingPageLookup !== null))
|
2021-07-23 19:23:31 +02:00
|
|
|
{
|
|
|
|
setIsVisible(true);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-07-29 08:03:30 +02:00
|
|
|
if(pendingPageLookup !== null || pendingOpenTree)
|
2021-07-23 19:23:31 +02:00
|
|
|
{
|
2021-08-26 05:06:42 +02:00
|
|
|
let tree: INodeData[] = [];
|
2021-07-29 08:03:30 +02:00
|
|
|
|
|
|
|
if(pendingPageLookup !== null)
|
|
|
|
{
|
|
|
|
tree = BuildCatalogPageTree(catalogState.root, pendingPageLookup.value, pendingPageLookup.isOffer);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
tree = pendingOpenTree.slice();
|
|
|
|
}
|
2021-07-23 19:23:31 +02:00
|
|
|
|
|
|
|
setCurrentTab(tree.shift());
|
2021-07-29 08:03:30 +02:00
|
|
|
setPendingOpenTree(null);
|
2021-07-28 04:41:51 +02:00
|
|
|
setPendingPageLookup(null);
|
2021-07-27 21:00:10 +02:00
|
|
|
setPendingTree(tree);
|
2021-07-23 19:23:31 +02:00
|
|
|
}
|
2021-07-28 02:01:37 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
setCurrentTab(prevValue =>
|
|
|
|
{
|
|
|
|
if(catalogState.root.children.length)
|
|
|
|
{
|
|
|
|
if(prevValue)
|
|
|
|
{
|
|
|
|
if(catalogState.root.children.indexOf(prevValue) >= 0) return prevValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ((catalogState.root.children.length && catalogState.root.children[0]) || null);
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
});
|
|
|
|
}
|
2021-07-23 19:23:31 +02:00
|
|
|
}
|
2021-07-29 08:03:30 +02:00
|
|
|
}, [ isVisible, pendingPageLookup, pendingOpenTree, catalogState.root, setCurrentTab ]);
|
2021-05-10 19:11:16 +02:00
|
|
|
|
2021-06-12 04:53:56 +02:00
|
|
|
useEffect(() =>
|
|
|
|
{
|
|
|
|
if(!currentTab) return;
|
|
|
|
|
2021-08-26 04:29:02 +02:00
|
|
|
SendMessageHook(new GetCatalogPageComposer(currentTab.pageId, -1, CatalogMode.MODE_NORMAL));
|
2021-06-12 04:53:56 +02:00
|
|
|
}, [ currentTab ]);
|
|
|
|
|
2021-05-10 19:11:16 +02:00
|
|
|
useEffect(() =>
|
|
|
|
{
|
|
|
|
setRoomPreviewer(new RoomPreviewer(GetRoomEngine(), ++RoomPreviewer.PREVIEW_COUNTER));
|
|
|
|
|
|
|
|
return () =>
|
2021-05-05 09:14:54 +02:00
|
|
|
{
|
2021-05-10 19:11:16 +02:00
|
|
|
setRoomPreviewer(prevValue =>
|
|
|
|
{
|
|
|
|
prevValue.dispose();
|
|
|
|
|
|
|
|
return null;
|
|
|
|
});
|
2021-05-05 09:14:54 +02:00
|
|
|
}
|
2021-05-10 19:11:16 +02:00
|
|
|
}, []);
|
|
|
|
|
|
|
|
const currentNavigationPage = ((searchResult && searchResult.page) || currentTab);
|
2021-09-30 04:31:31 +02:00
|
|
|
const navigationHidden = !!(pageParser && pageParser.frontPageItems.length);
|
2021-04-22 05:26:30 +02:00
|
|
|
|
|
|
|
return (
|
2021-05-05 09:14:54 +02:00
|
|
|
<CatalogContextProvider value={ { catalogState, dispatchCatalogState } }>
|
2021-06-12 04:53:56 +02:00
|
|
|
<CatalogMessageHandler />
|
2021-05-05 09:14:54 +02:00
|
|
|
{ isVisible &&
|
2021-08-09 18:15:08 +02:00
|
|
|
<NitroCardView uniqueKey="catalog" className="nitro-catalog">
|
2021-07-29 08:03:30 +02:00
|
|
|
<NitroCardHeaderView headerText={ LocalizeText('catalog.title') } onCloseClick={ event => { saveActivePages(); setIsVisible(false); } } />
|
2021-05-05 09:14:54 +02:00
|
|
|
<NitroCardTabsView>
|
2021-07-04 04:23:55 +02:00
|
|
|
{ root && root.children.length && root.children.map((page, index) =>
|
2021-05-05 09:14:54 +02:00
|
|
|
{
|
2021-06-12 04:53:56 +02:00
|
|
|
return (
|
2021-07-04 04:23:55 +02:00
|
|
|
<NitroCardTabsItemView key={ index } isActive={ (currentTab === page) } onClick={ event => setCurrentTab(page) }>
|
2021-06-12 04:53:56 +02:00
|
|
|
{ page.localization }
|
|
|
|
</NitroCardTabsItemView>
|
|
|
|
);
|
2021-05-05 09:14:54 +02:00
|
|
|
}) }
|
|
|
|
</NitroCardTabsView>
|
|
|
|
<NitroCardContentView>
|
2021-09-30 04:31:31 +02:00
|
|
|
<NitroLayoutGrid>
|
2021-07-28 02:01:37 +02:00
|
|
|
{ currentNavigationPage && !navigationHidden &&
|
2021-09-30 04:31:31 +02:00
|
|
|
<NitroLayoutGridColumn size={ 3 }>
|
2021-07-25 07:33:30 +02:00
|
|
|
<CatalogNavigationView page={ currentNavigationPage } pendingTree={ pendingTree } setPendingTree={ setPendingTree } />
|
2021-09-30 04:31:31 +02:00
|
|
|
</NitroLayoutGridColumn> }
|
|
|
|
<NitroLayoutGridColumn size={ (navigationHidden ? 12 : 9) }>
|
2021-05-10 19:11:16 +02:00
|
|
|
<CatalogPageView roomPreviewer={ roomPreviewer } />
|
2021-09-30 04:31:31 +02:00
|
|
|
</NitroLayoutGridColumn>
|
|
|
|
</NitroLayoutGrid>
|
2021-05-05 09:14:54 +02:00
|
|
|
</NitroCardContentView>
|
|
|
|
</NitroCardView> }
|
2021-09-17 08:39:58 +02:00
|
|
|
<CatalogGiftView />
|
2021-05-05 09:14:54 +02:00
|
|
|
</CatalogContextProvider>
|
2021-04-22 05:26:30 +02:00
|
|
|
);
|
|
|
|
}
|