Skip to content

Instantly share code, notes, and snippets.

@mathjazz
Created January 13, 2025 20:29
Show Gist options
  • Save mathjazz/2417c464b7b232a9a4c99d68fb35e383 to your computer and use it in GitHub Desktop.
Save mathjazz/2417c464b7b232a9a4c99d68fb35e383 to your computer and use it in GitHub Desktop.
Centralized Notification parsing logic
Sideshow:pontoon mathjazz$ git diff a0b431cff0b6844dd1ba9018010db4010e11497e 4575dbf4d09b79fbac72467b07b8337767e28e4c translate/
diff --git a/translate/src/context/BadgeTooltip.tsx b/translate/src/context/BadgeTooltip.tsx
index aaf56db37..e79b6dba0 100644
--- a/translate/src/context/BadgeTooltip.tsx
+++ b/translate/src/context/BadgeTooltip.tsx
@@ -1,49 +1,17 @@
-import { createContext, useEffect, useState } from 'react';
-import { Localized } from '@fluent/react';
-
-export type BadgeTooltipMessage = Readonly<{
- badgeName: string | null;
- badgeLevel: number | null;
-}>;
-
-export const BadgeTooltipMessage = createContext<BadgeTooltipMessage | null>(
- null,
-);
-
-export const ShowBadgeTooltip = createContext<
- (tooltip: BadgeTooltipMessage | null) => void
->(() => {});
+import { useContext } from 'react';
+import { BadgeTooltipMessage, ShowBadgeTooltip } from './Notification';
export function BadgeTooltipProvider({
children,
}: {
children: React.ReactElement;
}) {
- const [message, setMessage] = useState<BadgeTooltipMessage | null>(null);
-
- useEffect(() => {
- const rootElt = document.getElementById('root');
- if (rootElt?.dataset.notifications) {
- const notifications = JSON.parse(rootElt.dataset.notifications);
- if (notifications.length > 0) {
- const parsed = notifications.map(
- (notification: { content: string; type: string }) => {
- if (notification.type === 'info') {
- // Badge update information
- return JSON.parse(notification.content);
- } else {
- return { content: notification.content, type: notification.type };
- }
- },
- );
- setMessage(parsed[1]);
- }
- }
- }, []);
+ const badgeMessage = useContext(BadgeTooltipMessage);
+ const setBadgeMessage = useContext(ShowBadgeTooltip);
return (
- <BadgeTooltipMessage.Provider value={message}>
- <ShowBadgeTooltip.Provider value={(tooltip) => setMessage(tooltip)}>
+ <BadgeTooltipMessage.Provider value={badgeMessage}>
+ <ShowBadgeTooltip.Provider value={setBadgeMessage}>
{children}
</ShowBadgeTooltip.Provider>
</BadgeTooltipMessage.Provider>
diff --git a/translate/src/context/Notification.tsx b/translate/src/context/Notification.tsx
index d51584157..41ac72f48 100644
--- a/translate/src/context/Notification.tsx
+++ b/translate/src/context/Notification.tsx
@@ -7,6 +7,11 @@ export type NotificationMessage = Readonly<{
content: string | React.ReactElement;
}>;
+export type BadgeTooltipMessage = Readonly<{
+ badgeName: string | null;
+ badgeLevel: number | null;
+}>;
+
export const NotificationMessage = createContext<NotificationMessage | null>(
null,
);
@@ -15,12 +20,23 @@ export const ShowNotification = createContext<
(message: NotificationMessage | null) => void
>(() => {});
+export const BadgeTooltipMessage = createContext<BadgeTooltipMessage | null>(
+ null,
+);
+
+export const ShowBadgeTooltip = createContext<
+ (tooltip: BadgeTooltipMessage | null) => void
+>(() => {});
+
export function NotificationProvider({
children,
}: {
children: React.ReactElement;
}) {
const [message, setMessage] = useState<NotificationMessage | null>(null);
+ const [badgeMessage, setBadgeMessage] = useState<BadgeTooltipMessage | null>(
+ null,
+ );
// If there's a notification in the DOM set by Django, show it.
// Note that we only show it once, and only when the UI has already
@@ -33,6 +49,27 @@ export function NotificationProvider({
// Our notification system only supports showing one notification
// for the moment, so we only add the first notification here.
setMessage(notifications[0]);
+ const generalNotification = notifications.find(
+ (notification: { type: string }) => notification.type !== 'info',
+ );
+ const badgeNotification = notifications.find(
+ (notification: { type: string }) => notification.type === 'info',
+ );
+
+ if (generalNotification) {
+ setMessage({
+ type: generalNotification.type,
+ content: generalNotification.content,
+ });
+ }
+
+ if (badgeNotification) {
+ const badgeData = JSON.parse(badgeNotification.content);
+ setBadgeMessage({
+ badgeName: badgeData.badgeName || null,
+ badgeLevel: badgeData.badgeLevel || null,
+ });
+ }
}
}
}, []);
@@ -40,7 +77,11 @@ export function NotificationProvider({
return (
<NotificationMessage.Provider value={message}>
<ShowNotification.Provider value={setMessage}>
- {children}
+ <BadgeTooltipMessage.Provider value={badgeMessage}>
+ <ShowBadgeTooltip.Provider value={setBadgeMessage}>
+ {children}
+ </ShowBadgeTooltip.Provider>
+ </BadgeTooltipMessage.Provider>
</ShowNotification.Provider>
</NotificationMessage.Provider>
);
diff --git a/translate/src/modules/batchactions/components/BatchActions.tsx b/translate/src/modules/batchactions/components/BatchActions.tsx
index 86bf12e29..4022c7b88 100644
--- a/translate/src/modules/batchactions/components/BatchActions.tsx
+++ b/translate/src/modules/batchactions/components/BatchActions.tsx
@@ -2,7 +2,7 @@ import { Localized } from '@fluent/react';
import React, { useCallback, useContext, useEffect, useRef } from 'react';
import { Location } from '~/context/Location';
-import { ShowBadgeTooltip } from '~/context/BadgeTooltip';
+import { ShowBadgeTooltip } from '~/context/Notification';
import { useAppDispatch, useAppSelector } from '~/hooks';
import { performAction, resetSelection, selectAll } from '../actions';
diff --git a/translate/src/modules/editor/components/BadgeTooltip.tsx b/translate/src/modules/editor/components/BadgeTooltip.tsx
index c68668c6e..d4e94801b 100644
--- a/translate/src/modules/editor/components/BadgeTooltip.tsx
+++ b/translate/src/modules/editor/components/BadgeTooltip.tsx
@@ -3,7 +3,7 @@ import React, { useCallback, useContext, useRef } from 'react';
import { Localized } from '@fluent/react';
import Pride from 'react-canvas-confetti/dist/presets/pride';
-import { BadgeTooltipMessage, ShowBadgeTooltip } from '~/context/BadgeTooltip';
+import { BadgeTooltipMessage, ShowBadgeTooltip } from '~/context/Notification';
import { useAppSelector } from '~/hooks';
import { useOnDiscard } from '~/utils';
diff --git a/translate/src/modules/editor/hooks/useSendTranslation.ts b/translate/src/modules/editor/hooks/useSendTranslation.ts
index aae03f6e5..93c7248d1 100644
--- a/translate/src/modules/editor/hooks/useSendTranslation.ts
+++ b/translate/src/modules/editor/hooks/useSendTranslation.ts
@@ -11,7 +11,7 @@ import { EntityView } from '~/context/EntityView';
import { FailedChecksData } from '~/context/FailedChecksData';
import { Locale } from '~/context/Locale';
import { Location } from '~/context/Location';
-import { ShowNotification } from '~/context/Notification';
+import { ShowBadgeTooltip, ShowNotification } from '~/context/Notification';
import { UnsavedActions } from '~/context/UnsavedChanges';
import { updateEntityTranslation } from '~/modules/entities/actions';
import { usePushNextTranslatable } from '~/modules/entities/hooks';
@@ -23,7 +23,6 @@ import { updateResource } from '~/modules/resource/actions';
import { updateStats } from '~/modules/stats/actions';
import { useAppDispatch, useAppSelector } from '~/hooks';
import { serializeEntry, getPlainMessage } from '~/utils/message';
-import { ShowBadgeTooltip } from '~/context/BadgeTooltip';
/**
* Return a function to send a translation to the server.
diff --git a/translate/src/modules/editor/hooks/useUpdateTranslationStatus.ts b/translate/src/modules/editor/hooks/useUpdateTranslationStatus.ts
index 2a00c46ff..ac786e59a 100644
--- a/translate/src/modules/editor/hooks/useUpdateTranslationStatus.ts
+++ b/translate/src/modules/editor/hooks/useUpdateTranslationStatus.ts
@@ -7,8 +7,7 @@ import { EntityView } from '~/context/EntityView';
import { FailedChecksData } from '~/context/FailedChecksData';
import { HistoryData } from '~/context/HistoryData';
import { Location } from '~/context/Location';
-import { ShowNotification } from '~/context/Notification';
-import { ShowBadgeTooltip } from '~/context/BadgeTooltip';
+import { ShowBadgeTooltip, ShowNotification } from '~/context/Notification';
import { updateEntityTranslation } from '~/modules/entities/actions';
import { usePushNextTranslatable } from '~/modules/entities/hooks';
import {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment