From fc11cb57944ced0f599663cc97eaf1974735a63f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Paczy=C5=84ski?= Date: Thu, 7 Dec 2023 10:38:02 +0100 Subject: [PATCH 1/8] Change start time to CET time --- src/shared/utils/timers.ts | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/shared/utils/timers.ts b/src/shared/utils/timers.ts index 303f772f..577d96df 100644 --- a/src/shared/utils/timers.ts +++ b/src/shared/utils/timers.ts @@ -16,11 +16,20 @@ export const formatDate = (date: Date): string => }) .toUpperCase() +export const convertDateToCETTimezone = () => { + const currentDate = new Date() + currentDate.setUTCHours(currentDate.getUTCHours() + 1) + + return currentDate +} + // This function calculates time remaining in the format: X days Y minutes remaining export const getTimeRemaining = (endDate: Date): string => { - const currentTimestamp = Date.now() + const currentDate = convertDateToCETTimezone() const endDateTimestamp = endDate.getTime() + const currentTimestamp = currentDate.getTime() + const timeRemainingTimestamp = endDateTimestamp - currentTimestamp const daysLeft = timeRemainingTimestamp / DAY @@ -51,10 +60,7 @@ export const getTimeRemaining = (endDate: Date): string => { * @returns timestamp of next selected day */ export function getNextSelectedWeekDay(weekDay: number, hour: number) { - const currentTimestamp = new Date() - - // Convert time to CET timezone - currentTimestamp.setUTCHours(currentTimestamp.getUTCHours() + 1) + const currentTimestamp = convertDateToCETTimezone() const currentHour = currentTimestamp.getHours() const daysLeft = (weekDay - currentTimestamp.getUTCDay() + 7) % 7 From 5d79eeeb46a29f175045254d59dba91db333dd0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Paczy=C5=84ski?= Date: Fri, 8 Dec 2023 09:44:48 +0100 Subject: [PATCH 2/8] Include timezone in time remaining calculation --- .../RealmPanel/RealmPanelCountdown.tsx | 2 +- src/shared/utils/timers.ts | 39 +++++++++++-------- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/shared/components/RealmPanel/RealmPanelCountdown.tsx b/src/shared/components/RealmPanel/RealmPanelCountdown.tsx index 1b7addf5..2dbcc119 100644 --- a/src/shared/components/RealmPanel/RealmPanelCountdown.tsx +++ b/src/shared/components/RealmPanel/RealmPanelCountdown.tsx @@ -16,7 +16,7 @@ export default function RealmPanelCountdown() { if (!weekEndDate) return null - const nextDropTimestamp = getNextSelectedWeekDay(4, 18) + const nextDropTimestamp = getNextSelectedWeekDay(4, 17) // 17:00 UTC time const timeRemaining = getTimeRemaining(nextDropTimestamp) return ( diff --git a/src/shared/utils/timers.ts b/src/shared/utils/timers.ts index 577d96df..e2924537 100644 --- a/src/shared/utils/timers.ts +++ b/src/shared/utils/timers.ts @@ -16,16 +16,16 @@ export const formatDate = (date: Date): string => }) .toUpperCase() -export const convertDateToCETTimezone = () => { +export const convertDateToUTCTimezone = () => { const currentDate = new Date() - currentDate.setUTCHours(currentDate.getUTCHours() + 1) + currentDate.setUTCHours(currentDate.getUTCHours()) return currentDate } // This function calculates time remaining in the format: X days Y minutes remaining export const getTimeRemaining = (endDate: Date): string => { - const currentDate = convertDateToCETTimezone() + const currentDate = convertDateToUTCTimezone() const endDateTimestamp = endDate.getTime() const currentTimestamp = currentDate.getTime() @@ -35,6 +35,9 @@ export const getTimeRemaining = (endDate: Date): string => { const daysLeft = timeRemainingTimestamp / DAY const hoursLeft = timeRemainingTimestamp / HOUR - Math.floor(daysLeft) * 24 + // If 24h hours left, convert it to one day + const adjustedDaysLeft = Math.ceil(hoursLeft) === 24 ? daysLeft + 1 : daysLeft + // If less than 1 hour left, display "coming soon" if (Math.floor(daysLeft) === 0 && hoursLeft < 1) { return XP_COMING_SOON_TEXT @@ -42,38 +45,42 @@ export const getTimeRemaining = (endDate: Date): string => { let timeRemainingText = "" - if (Math.floor(daysLeft) > 0) { + if (Math.floor(adjustedDaysLeft) > 0) { timeRemainingText += - Math.floor(daysLeft) === 1 ? "1 day " : `${Math.floor(daysLeft)} days ` + Math.floor(adjustedDaysLeft) === 1 + ? "1 day " + : `${Math.floor(adjustedDaysLeft)} days ` } - timeRemainingText += - Math.ceil(hoursLeft) === 1 ? "1 hour " : `${Math.ceil(hoursLeft)} hours ` + if (Math.ceil(hoursLeft) !== 24) { + timeRemainingText += `${Math.ceil(hoursLeft)} hours ` // if smaller than 1 hour, we display "XP drop coming soon" + } return `${timeRemainingText}remaining` } /** - This function returns next selected day (f.e. next Thursday) and CET time + This function returns next selected day (f.e. next Thursday) * @param weekDay day of the week (1 = Monday, 2 = Tuesday, etc.) * @param hour desired hour in 24h format * @returns timestamp of next selected day */ export function getNextSelectedWeekDay(weekDay: number, hour: number) { - const currentTimestamp = convertDateToCETTimezone() + const currentDate = convertDateToUTCTimezone() + const adjustedHour = hour - currentDate.getTimezoneOffset() / 60 - const currentHour = currentTimestamp.getHours() - const daysLeft = (weekDay - currentTimestamp.getUTCDay() + 7) % 7 + const currentHour = currentDate.getHours() + const daysLeft = (weekDay - currentDate.getUTCDay() + 7) % 7 // If the today and selected day are the same and it is passed selected hour, then choose next closest day const daysUntilSelectedDay = - daysLeft === 0 && currentHour >= hour ? 7 : daysLeft + daysLeft === 0 && currentHour >= adjustedHour ? 7 : daysLeft const nextSelectedDay = new Date( - currentTimestamp.getUTCFullYear(), - currentTimestamp.getUTCMonth(), - currentTimestamp.getUTCDate() + daysUntilSelectedDay, - hour, + currentDate.getUTCFullYear(), + currentDate.getUTCMonth(), + currentDate.getUTCDate() + daysUntilSelectedDay, + adjustedHour, 0, 0 ) From acce74ad262d60e853473ad195560cf11703bdef Mon Sep 17 00:00:00 2001 From: Piotr Kacprzyk Date: Fri, 8 Dec 2023 09:46:53 +0100 Subject: [PATCH 3/8] Add pageleave event tracking --- src/shared/hooks/helpers.ts | 14 ++++++++++++++ src/ui/DApps/index.tsx | 3 ++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/shared/hooks/helpers.ts b/src/shared/hooks/helpers.ts index 9e63832b..9b065f53 100644 --- a/src/shared/hooks/helpers.ts +++ b/src/shared/hooks/helpers.ts @@ -254,6 +254,20 @@ export function useMobileScreen() { return width < MOBILE_BREAKPOINT } +export function useUnLoad() { + const posthog = usePostHog() + + useEffect(() => { + const onUnload = () => { + posthog?.capture("$pageleave") + } + window.addEventListener("beforeunload", onUnload) + return () => { + window.removeEventListener("beforeunload", onUnload) + } + }, [posthog]) +} + export function useTrackEvents() { const location = useLocation() const posthog = usePostHog() diff --git a/src/ui/DApps/index.tsx b/src/ui/DApps/index.tsx index bad2729a..2419db15 100644 --- a/src/ui/DApps/index.tsx +++ b/src/ui/DApps/index.tsx @@ -1,5 +1,5 @@ import React from "react" -import { useMobileScreen, useTrackEvents } from "shared/hooks" +import { useMobileScreen, useTrackEvents, useUnLoad } from "shared/hooks" import GlobalStyles from "ui/GlobalStyles" import MobileDApp from "./MobileDApp" import DesktopDApp from "./DesktopDApp" @@ -7,6 +7,7 @@ import DesktopDApp from "./DesktopDApp" export default function DApp() { const isMobileScreen = useMobileScreen() useTrackEvents() + useUnLoad() return ( <> From a3a3bd4dbc195b0289f3e58593b12d149c870932 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Paczy=C5=84ski?= Date: Fri, 8 Dec 2023 14:34:52 +0100 Subject: [PATCH 4/8] Close realm panel on outside click --- src/shared/hooks/realm.ts | 27 +++++++++++++++++++++++++-- src/ui/Island/RealmPanel/index.tsx | 9 +++++++++ src/ui/Island/index.tsx | 15 +++------------ 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/src/shared/hooks/realm.ts b/src/shared/hooks/realm.ts index d1290e22..93733ec5 100644 --- a/src/shared/hooks/realm.ts +++ b/src/shared/hooks/realm.ts @@ -1,6 +1,12 @@ import { easings, useSpring } from "@react-spring/web" -import { useMemo } from "react" -import { selectRealmPanelVisible, useDappSelector } from "redux-state" +import { useCallback, useMemo } from "react" +import { + selectRealmPanelVisible, + setDisplayedRealmId, + setRealmPanelVisible, + useDappDispatch, + useDappSelector, +} from "redux-state" import { REALM_PANEL_ANIMATION_TIME } from "shared/constants" import { useTabletScreen } from "./helpers" @@ -71,3 +77,20 @@ export function useRealmCloseButtonTransition() { return buttonTransition } + +export function usePanelRealmClose() { + const dispatch = useDappDispatch() + + const handleClickOutside = useCallback(() => { + dispatch(setRealmPanelVisible(false)) + + const timeout = setTimeout( + () => dispatch(setDisplayedRealmId(null)), + REALM_PANEL_ANIMATION_TIME + ) + + return () => clearTimeout(timeout) + }, [dispatch]) + + return handleClickOutside +} diff --git a/src/ui/Island/RealmPanel/index.tsx b/src/ui/Island/RealmPanel/index.tsx index 69cfa0a6..bafa6c15 100644 --- a/src/ui/Island/RealmPanel/index.tsx +++ b/src/ui/Island/RealmPanel/index.tsx @@ -2,9 +2,12 @@ import React, { useEffect } from "react" import { useAssistant, useLocalStorageChange, + usePanelRealmClose, useTabletScreen, } from "shared/hooks" import { LOCAL_STORAGE_VISITED_REALM } from "shared/constants" +import { selectRealmPanelVisible, useDappSelector } from "redux-state" +import ClickableModalOverlay from "shared/components/Dialogs/ClickableModalOverlay" import RealmDetailsPanel from "./RealmDetailsPanel" import RealmLeaderboardPanel from "./RealmLeaderboardPanel" import RealmPanelCountdown from "./RealmPanelCountdown" @@ -18,6 +21,9 @@ export default function RealmPanel({ onClose }: { onClose: () => void }) { LOCAL_STORAGE_VISITED_REALM ) + const realmPanelVisible = useDappSelector(selectRealmPanelVisible) + const handleClickOutside = usePanelRealmClose() + useEffect(() => { if (value) return updateStorage(true) @@ -37,6 +43,9 @@ export default function RealmPanel({ onClose }: { onClose: () => void }) { )} + {realmPanelVisible && ( + + )} ) } diff --git a/src/ui/Island/index.tsx b/src/ui/Island/index.tsx index 0aa33ed0..982d93fa 100644 --- a/src/ui/Island/index.tsx +++ b/src/ui/Island/index.tsx @@ -1,10 +1,11 @@ -import React, { memo, useCallback, useEffect } from "react" +import React, { memo, useEffect } from "react" import backgroundImg from "public/dapp_island_bg.webp" import { useValueRef, IslandContext, useAssistant, useAssets, + usePanelRealmClose, } from "shared/hooks" import { selectDisplayedRealmId, @@ -17,7 +18,6 @@ import { import FullPageLoader from "shared/components/Loaders/FullPageLoader" import { usePostHog } from "posthog-js/react" import RealmPanel from "ui/Island/RealmPanel" -import { REALM_PANEL_ANIMATION_TIME } from "shared/constants" import InteractiveIsland from "./Background/InteractiveIsland" import IslandPresence from "./Reflect/IslandPresence" @@ -52,16 +52,7 @@ function IslandWrapper() { }, })) - const handleClose = useCallback(() => { - dispatch(setRealmPanelVisible(false)) - - const timeout = setTimeout( - () => dispatch(setDisplayedRealmId(null)), - REALM_PANEL_ANIMATION_TIME - ) - - return () => clearTimeout(timeout) - }, [dispatch]) + const handleClose = usePanelRealmClose() return ( <> From d1602e3862df084f27d0d30f5345f469daa49a80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Paczy=C5=84ski?= Date: Fri, 8 Dec 2023 14:54:09 +0100 Subject: [PATCH 5/8] Close modal on panel container click --- src/shared/components/Dialogs/Panel.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/shared/components/Dialogs/Panel.tsx b/src/shared/components/Dialogs/Panel.tsx index e36cc4b9..edac72ef 100644 --- a/src/shared/components/Dialogs/Panel.tsx +++ b/src/shared/components/Dialogs/Panel.tsx @@ -1,7 +1,7 @@ import React, { ReactNode, CSSProperties } from "react" import classNames from "classnames" import { animated } from "@react-spring/web" -import { useRealmPanelTransition } from "shared/hooks" +import { usePanelRealmClose, useRealmPanelTransition } from "shared/hooks" import Portal from "../Interface/Portal" type PortalSectionProps = { @@ -36,12 +36,17 @@ function Container({ style, }: PanelContainerProps) { const containerTransitionStyles = useRealmPanelTransition(position) + const closePanel = usePanelRealmClose() return ( { + if (e.target !== e.currentTarget) return + closePanel() + }} >
Date: Fri, 8 Dec 2023 15:03:37 +0100 Subject: [PATCH 6/8] Put realm panel close button into `Portal` --- .../RealmPanel/RealmPanelCloseButton.tsx | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/ui/Island/RealmPanel/RealmPanelCloseButton.tsx b/src/ui/Island/RealmPanel/RealmPanelCloseButton.tsx index 6949ea45..1b1c3da3 100644 --- a/src/ui/Island/RealmPanel/RealmPanelCloseButton.tsx +++ b/src/ui/Island/RealmPanel/RealmPanelCloseButton.tsx @@ -3,6 +3,7 @@ import closeIcon from "shared/assets/icons/s/close-black.svg" import { animated } from "@react-spring/web" import { useRealmCloseButtonTransition } from "shared/hooks" import Button from "../../../shared/components/Interface/Button" +import Portal from "shared/components/Interface/Portal" export default function RealmPanelCloseButton({ onClose, @@ -12,16 +13,18 @@ export default function RealmPanelCloseButton({ const buttonTransition = useRealmCloseButtonTransition() return ( - - - + + + + + ) } From 694d0d32207c2f619f982a6c30b0be0f05cdc3d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Paczy=C5=84ski?= Date: Fri, 8 Dec 2023 15:13:04 +0100 Subject: [PATCH 7/8] Function rename --- src/shared/hooks/realm.ts | 4 ++-- src/ui/Island/RealmPanel/index.tsx | 6 ++---- src/ui/Island/index.tsx | 4 ++-- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/shared/hooks/realm.ts b/src/shared/hooks/realm.ts index 93733ec5..9d991a14 100644 --- a/src/shared/hooks/realm.ts +++ b/src/shared/hooks/realm.ts @@ -81,7 +81,7 @@ export function useRealmCloseButtonTransition() { export function usePanelRealmClose() { const dispatch = useDappDispatch() - const handleClickOutside = useCallback(() => { + const handlePanelClose = useCallback(() => { dispatch(setRealmPanelVisible(false)) const timeout = setTimeout( @@ -92,5 +92,5 @@ export function usePanelRealmClose() { return () => clearTimeout(timeout) }, [dispatch]) - return handleClickOutside + return handlePanelClose } diff --git a/src/ui/Island/RealmPanel/index.tsx b/src/ui/Island/RealmPanel/index.tsx index bafa6c15..6e573615 100644 --- a/src/ui/Island/RealmPanel/index.tsx +++ b/src/ui/Island/RealmPanel/index.tsx @@ -22,7 +22,7 @@ export default function RealmPanel({ onClose }: { onClose: () => void }) { ) const realmPanelVisible = useDappSelector(selectRealmPanelVisible) - const handleClickOutside = usePanelRealmClose() + const handlePanelClose = usePanelRealmClose() useEffect(() => { if (value) return @@ -43,9 +43,7 @@ export default function RealmPanel({ onClose }: { onClose: () => void }) { )} - {realmPanelVisible && ( - - )} + {realmPanelVisible && } ) } diff --git a/src/ui/Island/index.tsx b/src/ui/Island/index.tsx index 982d93fa..b364c509 100644 --- a/src/ui/Island/index.tsx +++ b/src/ui/Island/index.tsx @@ -52,7 +52,7 @@ function IslandWrapper() { }, })) - const handleClose = usePanelRealmClose() + const handlePanelClose = usePanelRealmClose() return ( <> @@ -71,7 +71,7 @@ function IslandWrapper() { {process.env.DISABLE_REFLECT === "true" ? null : } - +
From 38041e1b833f54c6b1d29be5079f5c1771ed7999 Mon Sep 17 00:00:00 2001 From: Jagoda Berry Rybacka Date: Fri, 8 Dec 2023 15:20:45 +0100 Subject: [PATCH 8/8] Hardcode season duration To get better UX for now let's change season duration to 7 weeks so it indicates this is the last week of beta. --- src/ui/Island/RealmPanel/RealmPanelCountdown.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ui/Island/RealmPanel/RealmPanelCountdown.tsx b/src/ui/Island/RealmPanel/RealmPanelCountdown.tsx index ba15dbb3..69d13632 100644 --- a/src/ui/Island/RealmPanel/RealmPanelCountdown.tsx +++ b/src/ui/Island/RealmPanel/RealmPanelCountdown.tsx @@ -1,6 +1,6 @@ import React from "react" import { - selectSeasonDurationInWeeks, + // selectSeasonDurationInWeeks, selectSeasonWeek, selectWeekEndDate, useDappSelector, @@ -11,7 +11,8 @@ import Icon from "shared/components/Media/Icon" export default function RealmPanelCountdown() { const seasonWeek = useDappSelector(selectSeasonWeek) - const seasonDuration = useDappSelector(selectSeasonDurationInWeeks) + // TODO: for now we are hardcoding the season duration to 7 weeks to get better UX + const seasonDuration = 7 // useDappSelector(selectSeasonDurationInWeeks) const weekEndDate = useDappSelector(selectWeekEndDate) if (!weekEndDate) return null