This commit is contained in:
dank074 2021-11-26 01:31:06 -06:00
parent 8b2cef7f93
commit 3eb4757d98
15 changed files with 206 additions and 19 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 448 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

View File

@ -14,7 +14,7 @@ export const CampaignView: FC<{}> = props =>
const parser = event.getParser(); const parser = event.getParser();
if(!parser) return; if(!parser) return;
console.log(parser);
setCalendarData(parser.calendarData); setCalendarData(parser.calendarData);
}, []); }, []);

View File

@ -0,0 +1,7 @@
export class CalendarItemState
{
public static readonly STATE_UNLOCKED = 1;
public static readonly STATE_LOCKED_AVAILABLE = 2;
public static readonly STATE_LOCKED_EXPIRED = 3;
public static readonly STATE_LOCKED_FUTURE = 4;
}

View File

@ -0,0 +1,4 @@
export const getNumItemsDisplayed = (): number =>
{
return Math.max(Math.min(2, window.screen.width / 135), 7);
}

View File

@ -1,10 +1,46 @@
import { FC } from 'react'; import { FC, useCallback } from 'react';
import { GetRoomEngine, GetSessionDataManager } from '../../../../api';
import { NitroLayoutFlexColumn } from '../../../../layout'; import { NitroLayoutFlexColumn } from '../../../../layout';
import { CalendarItemState } from '../../common/CalendarItemState';
import { CalendarItemViewProps } from './CalendarItemView.types'; import { CalendarItemViewProps } from './CalendarItemView.types';
export const CalendarItemView: FC<CalendarItemViewProps> = props => export const CalendarItemView: FC<CalendarItemViewProps> = props =>
{ {
const { state = null, productName = null, active = false, onClick = null, id = null } = props;
const getFurnitureIcon = useCallback((name: string) =>
{
let furniData = GetSessionDataManager().getFloorItemDataByName(name);
let url = null;
if(furniData) url = GetRoomEngine().getFurnitureFloorIconUrl(furniData.id);
else
{
furniData = GetSessionDataManager().getWallItemDataByName(name);
if(furniData) url = GetRoomEngine().getFurnitureWallIconUrl(furniData.id);
}
return url;
}, []);
return ( return (
<NitroLayoutFlexColumn className="calendar-day h-100 w-100" /> <NitroLayoutFlexColumn className={`calendar-item h-100 w-100 cursor-pointer align-items-center justify-content-center ${active ? 'active' : ''}`} onClick={() => onClick(id)}>
{ (state === CalendarItemState.STATE_UNLOCKED) &&
<div className="unlocked-generic-bg">
</div>
}
{ (state !== CalendarItemState.STATE_UNLOCKED) &&
<div className="locked-generic-bg d-flex justify-content-center align-items-center">
{ (state === CalendarItemState.STATE_LOCKED_AVAILABLE) &&
<div className="available"/>
}
{ (state === CalendarItemState.STATE_LOCKED_EXPIRED || state === CalendarItemState.STATE_LOCKED_FUTURE) &&
<div className="unavailable" />
}
</div>
}
</NitroLayoutFlexColumn>
); );
} }

View File

@ -1,4 +1,8 @@
export interface CalendarItemViewProps export interface CalendarItemViewProps
{ {
id: number;
productName?: string;
state: number;
active?: boolean;
onClick(itemId: number): void;
} }

View File

@ -1,10 +1,69 @@
.nitro-campaign-calendar { .nitro-campaign-calendar {
width: 800px; width: 1010px;
height: 400px; height: 400px;
.calendar-day { .calendar-item {
background: url('../../../../assets/images/campaign/campaign_day_generic_bg.png'); background: url("../../../../assets/images/campaign/campaign_day_generic_bg.png");
max-height: 100%; max-height: 100%;
min-width: 50px; min-width: 135px;
filter: brightness(80%);
&.active {
filter: brightness(100%);
}
.unlocked-generic-bg {
background: url("../../../../assets/images/campaign/unlocked_bg.png");
background-size: 132px 132px;
width: 132px;
height: 132px;
//width: 190px;
//height: 189px;
}
.locked-generic-bg {
background: url("../../../../assets/images/campaign/locked_bg.png");
width: 132px;
height: 132px;
.available {
background: url("../../../../assets/images/campaign/available.png");
width: 69px;
height: 78px;
}
.unavailable {
background: url("../../../../assets/images/campaign/unavailable.png");
width: 68px;
height: 78px;
}
}
}
.button-container {
position: relative;
width: 100%;
height: 0px;
.calendar-prev {
background: url("../../../../assets/images/campaign/prev.png");
width: 33px;
height: 34px;
position: absolute;
margin-top: 15%;
left: 5px;
z-index: 10;
}
.calendar-next {
background: url("../../../../assets/images/campaign/next.png");
width: 33px;
height: 34px;
position: absolute;
margin-top: 15%;
right: 5px;
z-index: 10;
}
} }
} }

View File

@ -1,6 +1,8 @@
import { FC, useCallback, useState } from 'react'; import { FC, useCallback, useState } from 'react';
import { LocalizeText } from '../../../../api'; import { LocalizeText } from '../../../../api';
import { NitroCardContentView, NitroCardHeaderView, NitroCardView, NitroLayoutFlex } from '../../../../layout'; import { NitroCardContentView, NitroCardHeaderView, NitroCardView, NitroLayoutFlex } from '../../../../layout';
import { CalendarItemState } from '../../common/CalendarItemState';
import { getNumItemsDisplayed } from '../../common/Utils';
import { CalendarItemView } from '../calendar-item/CalendarItemView'; import { CalendarItemView } from '../calendar-item/CalendarItemView';
import { CalendarViewProps } from './CalendarView.types'; import { CalendarViewProps } from './CalendarView.types';
@ -8,30 +10,104 @@ export const CalendarView: FC<CalendarViewProps> = props =>
{ {
const { close = null, campaignName = null, currentDay = null, numDays = null, missedDays = null, openedDays = null } = props; const { close = null, campaignName = null, currentDay = null, numDays = null, missedDays = null, openedDays = null } = props;
const [ selectedDay, setSelectedDay ] = useState(currentDay); const [ selectedDay, setSelectedDay ] = useState(currentDay);
const [ index, setIndex ] = useState(0);
const getDayState = useCallback((day: number) =>
{
if(openedDays.includes(day))
{
return CalendarItemState.STATE_UNLOCKED;
}
if(day > currentDay)
{
return CalendarItemState.STATE_LOCKED_FUTURE;
}
if(missedDays.includes(day))
{
return CalendarItemState.STATE_LOCKED_EXPIRED;
}
return CalendarItemState.STATE_LOCKED_AVAILABLE;
}, [currentDay, missedDays, openedDays]);
const dayMessage = useCallback((day: number) => const dayMessage = useCallback((day: number) =>
{ {
if(missedDays.includes(day)) const state = getDayState(day);
switch(state)
{ {
case CalendarItemState.STATE_UNLOCKED:
return LocalizeText('campaign.calendar.info.unlocked');
case CalendarItemState.STATE_LOCKED_FUTURE:
return LocalizeText('campaign.calendar.info.future');
case CalendarItemState.STATE_LOCKED_EXPIRED:
return LocalizeText('campaign.calendar.info.expired'); return LocalizeText('campaign.calendar.info.expired');
default: return LocalizeText('campaign.calendar.info.available.desktop');
}
}, [getDayState]);
const onClickNext = useCallback(() =>
{
const nextDay = selectedDay + 1;
if( (nextDay) === numDays) return;
setSelectedDay(nextDay);
if( (index + getNumItemsDisplayed()) < nextDay + 1 )
{
setIndex(index + 1);
} }
if(openedDays.includes(day)) }, [index, numDays, selectedDay]);
const onClickPrev = useCallback(() =>
{ {
return LocalizeText('campaign.calendar.info.unlocked') const prevDay = selectedDay - 1;
if( (prevDay < 0)) return;
setSelectedDay(prevDay);
if( index > prevDay)
{
setIndex(index - 1);
} }
}, [missedDays, openedDays]); }, [index, selectedDay]);
const onClickItem = useCallback((item: number) =>
{
if(selectedDay === item)
{
//handle opening
}
else
{
setSelectedDay(item);
}
}, [selectedDay]);
return ( return (
<NitroCardView className="nitro-campaign-calendar"> <NitroCardView className="nitro-campaign-calendar">
<NitroCardHeaderView headerText={ LocalizeText(`campaign.calendar.${campaignName}.title`) } onCloseClick={ close }/> <NitroCardHeaderView headerText={ LocalizeText(`campaign.calendar.${campaignName}.title`) } onCloseClick={ close }/>
<NitroCardContentView> <NitroCardContentView>
<div className="text-black"> <div className="text-black">
<h3>{ LocalizeText('campaign.calendar.heading.day', ['number'], [selectedDay.toString()]) }</h3> <h3>{ LocalizeText('campaign.calendar.heading.day', ['number'], [(selectedDay + 1).toString()]) }</h3>
<p>{ LocalizeText('') }</p> <p>{ dayMessage(selectedDay) }</p>
</div>
<div className="button-container">
<div className="calendar-prev cursor-pointer" onClick={ onClickPrev }/>
<div className="calendar-next cursor-pointer" onClick={ onClickNext }/>
</div> </div>
<NitroLayoutFlex className="h-100" gap={ 2 }> <NitroLayoutFlex className="h-100" gap={ 2 }>
{ [...Array(7)].map((e, i) => <CalendarItemView key={ i } /> ) } {
[...Array(getNumItemsDisplayed())].map((e, i) =>
{
const day = index + i;
return <CalendarItemView key={ i } state={ getDayState(day) } active={selectedDay === day} onClick={onClickItem} id={day}/>
})
}
</NitroLayoutFlex> </NitroLayoutFlex>
</NitroCardContentView> </NitroCardContentView>
</NitroCardView> </NitroCardView>

View File

@ -106,9 +106,8 @@ export const WordQuizWidgetView: FC<{}> = props =>
{ {
setUserAnswers(prev => setUserAnswers(prev =>
{ {
const copy = new Map(prev);
const keysToRemove: number[] = []; const keysToRemove: number[] = [];
copy.forEach((value, key) => prev.forEach((value, key) =>
{ {
value.secondsLeft--; value.secondsLeft--;
@ -118,8 +117,10 @@ export const WordQuizWidgetView: FC<{}> = props =>
} }
}); });
keysToRemove.forEach(key => copy.delete(key)); if(keysToRemove.length === 0) return prev;
const copy = new Map(prev);
keysToRemove.forEach(key => copy.delete(key));
return copy; return copy;
}) })