diff --git a/apps/web/components/Gw2Api/Gw2AccountSubscriptionProvider.tsx b/apps/web/components/Gw2Api/Gw2AccountSubscriptionProvider.tsx index 3d76cdb5e..370f4e9ef 100644 --- a/apps/web/components/Gw2Api/Gw2AccountSubscriptionProvider.tsx +++ b/apps/web/components/Gw2Api/Gw2AccountSubscriptionProvider.tsx @@ -40,7 +40,8 @@ type Cache = { type SubscriptionContext = (type: T, accountId: string, callback: SubscriptionCallback) => CancelSubscription; -const context = createContext>(() => () => {}); +const subscriptionContext = createContext>(() => () => {}); +const hasActiveSubscriptionContext = createContext(false); function hasType(type: T) { return (subscription: ActiveSubscription): subscription is ActiveSubscription => subscription.type === type; @@ -175,14 +176,16 @@ export const Gw2AccountSubscriptionProvider: FC - {children} - + + 0}> + {children} + + ); }; export function useSubscribe(type: T, accountId: string, callback: SubscriptionCallback) { - const subscribe = useContext(context); + const subscribe = useContext(subscriptionContext); useEffect( () => subscribe(type, accountId, callback), @@ -200,6 +203,10 @@ export function useSubscription(type: T, accountId: return data === undefined ? { loading: true } : { loading: false, ...data }; } +export function usePageHasActiveSubscriptions() { + return useContext(hasActiveSubscriptionContext); +} + function useInterval(active: boolean = false, seconds: number, callback: () => void) { const callbackRef = useRefTo(callback); const activeRef = useRefTo(active); diff --git a/apps/web/components/Layout/Header/LiveUpdateStatus.module.css b/apps/web/components/Layout/Header/LiveUpdateStatus.module.css new file mode 100644 index 000000000..afb682359 --- /dev/null +++ b/apps/web/components/Layout/Header/LiveUpdateStatus.module.css @@ -0,0 +1,16 @@ +.live { + display: inline-block; + width: 8px; + height: 8px; + color: #ef5350; + background-color: currentColor; + border-radius: 4px; + vertical-align: 2px; + margin-right: 8px; + animation: live ease-in 2s infinite; +} + +@keyframes live { + 0% { box-shadow: 0 0 0 0 currentColor; } + 40% { box-shadow: 0 0 0 4px transparent; } +} diff --git a/apps/web/components/Layout/Header/LiveUpdateStatus.tsx b/apps/web/components/Layout/Header/LiveUpdateStatus.tsx new file mode 100644 index 000000000..0249df04e --- /dev/null +++ b/apps/web/components/Layout/Header/LiveUpdateStatus.tsx @@ -0,0 +1,23 @@ +'use client'; + +import { usePageHasActiveSubscriptions } from '@/components/Gw2Api/Gw2AccountSubscriptionProvider'; +import { Button } from '@gw2treasures/ui/components/Form/Button'; +import type { FC } from 'react'; +import styles from './LiveUpdateStatus.module.css'; +import { DropDown } from '@gw2treasures/ui/components/DropDown/DropDown'; + +export interface LiveUpdateStatusProps {} + +export const LiveUpdateStatus: FC = ({}) => { + const live = usePageHasActiveSubscriptions(); + + if(!live) { + return null; + } + + return ( + Live}> +

Your account data on this page
is automatically updating.

+
+ ); +}; diff --git a/apps/web/components/Layout/Layout.tsx b/apps/web/components/Layout/Layout.tsx index 6331cb2eb..90fe18803 100644 --- a/apps/web/components/Layout/Layout.tsx +++ b/apps/web/components/Layout/Layout.tsx @@ -13,6 +13,7 @@ import { ReviewCountBadge } from './Header/ReviewCountBadge'; import { UserButton } from './Header/UserButton'; import { translations as itemTypeTranslations } from '../Item/ItemType.translations'; import { Rarity } from '@gw2treasures/database'; +import { LiveUpdateStatus } from './Header/LiveUpdateStatus'; interface LayoutProps { children: ReactNode; @@ -44,6 +45,7 @@ const Layout: FC = ({ children }) => { gw2treasures.com +
Review