diff --git a/src/assets/images/campaign/campaign_day_generic_bg.png b/src/assets/images/campaign/campaign_day_generic_bg.png new file mode 100644 index 00000000..25b3c622 Binary files /dev/null and b/src/assets/images/campaign/campaign_day_generic_bg.png differ diff --git a/src/assets/images/campaign/campaign_opened.png b/src/assets/images/campaign/campaign_opened.png new file mode 100644 index 00000000..9ec1bb30 Binary files /dev/null and b/src/assets/images/campaign/campaign_opened.png differ diff --git a/src/assets/images/campaign/locked.png b/src/assets/images/campaign/locked.png new file mode 100644 index 00000000..3805e502 Binary files /dev/null and b/src/assets/images/campaign/locked.png differ diff --git a/src/assets/images/campaign/unopened.png b/src/assets/images/campaign/unopened.png new file mode 100644 index 00000000..71a754ff Binary files /dev/null and b/src/assets/images/campaign/unopened.png differ diff --git a/src/views/Styles.scss b/src/views/Styles.scss index a727aa12..4a7438ed 100644 --- a/src/views/Styles.scss +++ b/src/views/Styles.scss @@ -24,3 +24,4 @@ @import './help/HelpView'; @import './floorplan-editor/FloorplanEditorView'; @import './nitropedia/NitropediaView'; +@import './campaign/CampaignView'; diff --git a/src/views/campaign/CampaignView.scss b/src/views/campaign/CampaignView.scss new file mode 100644 index 00000000..506d0169 --- /dev/null +++ b/src/views/campaign/CampaignView.scss @@ -0,0 +1 @@ +@import './views/calendar/CalendarView'; diff --git a/src/views/campaign/CampaignView.tsx b/src/views/campaign/CampaignView.tsx new file mode 100644 index 00000000..eb205f51 --- /dev/null +++ b/src/views/campaign/CampaignView.tsx @@ -0,0 +1,60 @@ +import { CampaignCalendarData, CampaignCalendarDataMessageEvent } from '@nitrots/nitro-renderer'; +import { FC, useCallback, useEffect, useState } from 'react'; +import { AddEventLinkTracker, RemoveLinkEventTracker } from '../../api'; +import { CreateMessageHook } from '../../hooks'; +import { CalendarView } from './views/calendar/CalendarView'; + +export const CampaignView: FC<{}> = props => +{ + const [ calendarData, setCalendarData ] = useState(null); + const [ isCalendarOpen, setCalendarOpen ] = useState(false); + + const onCampaignCalendarDataMessageEvent = useCallback((event: CampaignCalendarDataMessageEvent) => + { + const parser = event.getParser(); + + if(!parser) return; + + setCalendarData(parser.calendarData); + }, []); + + CreateMessageHook(CampaignCalendarDataMessageEvent, onCampaignCalendarDataMessageEvent); + + const onLinkReceived = useCallback((link: string) => + { + const value = link.split('/'); + + if(value.length < 2) return; + + switch(value[1]) + { + case 'calendar': + setCalendarOpen(true); + break; + } + }, []); + + useEffect(() => + { + const linkTracker = { linkReceived: onLinkReceived, eventUrlPrefix: 'openView/' }; + AddEventLinkTracker(linkTracker); + + return () => + { + RemoveLinkEventTracker(linkTracker); + } + }, [onLinkReceived]); + + const onCalendarClose = useCallback(() => + { + setCalendarOpen(false); + }, []); + + return ( + <> + {(calendarData && isCalendarOpen) && + + } + + ) +} diff --git a/src/views/campaign/views/calendar/CalendarView.scss b/src/views/campaign/views/calendar/CalendarView.scss new file mode 100644 index 00000000..7ef04128 --- /dev/null +++ b/src/views/campaign/views/calendar/CalendarView.scss @@ -0,0 +1,10 @@ +.nitro-campaign-calendar { + width: 800px; + height: 400px; + + .calendar-day { + background: url('../../../../assets/images/campaign/campaign_day_generic_bg.png'); + max-height: 100%; + min-width: 50px; + } +} diff --git a/src/views/campaign/views/calendar/CalendarView.tsx b/src/views/campaign/views/calendar/CalendarView.tsx new file mode 100644 index 00000000..72cc86fd --- /dev/null +++ b/src/views/campaign/views/calendar/CalendarView.tsx @@ -0,0 +1,43 @@ +import { FC, useCallback, useState } from 'react'; +import { LocalizeText } from '../../../../api'; +import { NitroCardContentView, NitroCardGridItemView, NitroCardGridView, NitroCardHeaderView, NitroCardView } from '../../../../layout'; +import { CalendarViewProps } from './CalendarView.types'; + +export const CalendarView: FC = props => +{ + const { close = null, campaignName = null, currentDay = null, numDays = null, missedDays = null, openedDays = null } = props; + const [ selectedDay, setSelectedDay ] = useState(currentDay); + + const dayMessage = useCallback((day: number) => + { + if(missedDays.includes(day)) + { + return LocalizeText('campaign.calendar.info.expired'); + } + + if(openedDays.includes(day)) + { + return LocalizeText('campaign.calendar.info.unlocked') + } + }, [missedDays, openedDays]); + + return ( + + + +
+

{LocalizeText('campaign.calendar.heading.day', ['number'], [selectedDay.toString()])}

+

{LocalizeText('')}

+
+ + { + [...Array(7)].map((e, i) => + { + return + }) + } + +
+
+ ) +} diff --git a/src/views/campaign/views/calendar/CalendarView.types.ts b/src/views/campaign/views/calendar/CalendarView.types.ts new file mode 100644 index 00000000..77539e8e --- /dev/null +++ b/src/views/campaign/views/calendar/CalendarView.types.ts @@ -0,0 +1,9 @@ +export interface CalendarViewProps +{ + close(): void; + campaignName: string; + currentDay: number; + numDays: number; + openedDays: number[]; + missedDays: number[]; +} diff --git a/src/views/main/MainView.tsx b/src/views/main/MainView.tsx index 5cd09f84..ca00b8dc 100644 --- a/src/views/main/MainView.tsx +++ b/src/views/main/MainView.tsx @@ -6,6 +6,7 @@ import { TransitionAnimation, TransitionAnimationTypes } from '../../layout'; import { AchievementsView } from '../achievements/AchievementsView'; import { AvatarEditorView } from '../avatar-editor/AvatarEditorView'; import { CameraWidgetView } from '../camera/CameraWidgetView'; +import { CampaignView } from '../campaign/CampaignView'; import { CatalogView } from '../catalog/CatalogView'; import { ChatHistoryView } from '../chat-history/ChatHistoryView'; import { FloorplanEditorView } from '../floorplan-editor/FloorplanEditorView'; @@ -77,6 +78,7 @@ export const MainView: FC = props => + ); }