diff --git a/app/components/layout/NotificationPopover.tsx b/app/components/layout/NotificationPopover.tsx
index e29a33787..08599d3bc 100644
--- a/app/components/layout/NotificationPopover.tsx
+++ b/app/components/layout/NotificationPopover.tsx
@@ -1,29 +1,34 @@
-import { useLocation } from "@remix-run/react";
+import { useLocation, useMatches, useRevalidator } from "@remix-run/react";
import clsx from "clsx";
import * as React from "react";
import { useTranslation } from "react-i18next";
-import { useUser } from "~/features/auth/core/user";
import {
NotificationItem,
NotificationItemDivider,
NotificationsList,
} from "~/features/notifications/components/NotificationList";
import { NOTIFICATIONS } from "~/features/notifications/notifications-contants";
-import { useNotifications } from "~/hooks/swr";
+import type { RootLoaderData } from "~/root";
import { NOTIFICATIONS_URL } from "~/utils/urls";
import { useMarkNotificationsAsSeen } from "../../features/notifications/notifications-hooks";
-import type { LoaderNotification } from "../../features/notifications/routes/notifications.peek";
import { LinkButton } from "../Button";
import { SendouButton } from "../elements/Button";
import { SendouPopover } from "../elements/Popover";
import { BellIcon } from "../icons/Bell";
import { RefreshIcon } from "../icons/Refresh";
+
import styles from "./NotificationPopover.module.css";
+export type LoaderNotification = NonNullable<
+ RootLoaderData["notifications"]
+>[number];
+
export function NotificationPopover() {
const location = useLocation();
- const user = useUser();
- const { notifications, isLoading, refresh } = useNotifications();
+ const [root] = useMatches();
+
+ const notifications = (root.data as RootLoaderData | undefined)
+ ?.notifications;
const unseenIds = React.useMemo(
() =>
@@ -33,7 +38,7 @@ export function NotificationPopover() {
[notifications],
);
- if (!user) {
+ if (!notifications) {
return null;
}
@@ -56,8 +61,6 @@ export function NotificationPopover() {
@@ -67,15 +70,12 @@ export function NotificationPopover() {
function NotificationContent({
notifications,
unseenIds,
- refresh,
- isLoading,
}: {
notifications: LoaderNotification[];
unseenIds: number[];
- refresh: () => void;
- isLoading: boolean;
}) {
const { t } = useTranslation(["common"]);
+ const { revalidate, state } = useRevalidator();
useMarkNotificationsAsSeen(unseenIds);
@@ -89,16 +89,14 @@ function NotificationContent({
icon={}
variant="minimal"
className={styles.refreshButton}
- onPress={refresh}
- isDisabled={isLoading}
+ onPress={revalidate}
+ isDisabled={state !== "idle"}
/>
{notifications.length === 0 ? (
- {isLoading
- ? t("common:notifications.loading")
- : t("common:notifications.empty")}
+ {t("common:notifications.empty")}
) : (
diff --git a/app/features/notifications/components/NotificationList.tsx b/app/features/notifications/components/NotificationList.tsx
index 2ed95067f..ea6650f6c 100644
--- a/app/features/notifications/components/NotificationList.tsx
+++ b/app/features/notifications/components/NotificationList.tsx
@@ -2,11 +2,11 @@ import { Link } from "@remix-run/react";
import { formatDistance } from "date-fns";
import { useTranslation } from "react-i18next";
import { Image } from "~/components/Image";
+import type { LoaderNotification } from "~/components/layout/NotificationPopover";
import {
notificationLink,
notificationNavIcon,
} from "~/features/notifications/notifications-utils";
-import type { LoaderNotification } from "~/features/notifications/routes/notifications.peek";
import { databaseTimestampToDate } from "~/utils/dates";
import { navIconUrl } from "~/utils/urls";
import styles from "./NotificationList.module.css";
diff --git a/app/features/notifications/routes/notifications.peek.ts b/app/features/notifications/routes/notifications.peek.ts
deleted file mode 100644
index c3f1cfd5b..000000000
--- a/app/features/notifications/routes/notifications.peek.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import type { LoaderFunctionArgs } from "@remix-run/node";
-import { requireUser } from "~/features/auth/core/user.server";
-import type { SerializeFrom } from "~/utils/remix";
-import * as NotificationRepository from "../NotificationRepository.server";
-import { NOTIFICATIONS } from "../notifications-contants";
-
-export type NotificationsLoaderData = SerializeFrom;
-export type LoaderNotification =
- NotificationsLoaderData["notifications"][number];
-
-export const loader = async ({ request }: LoaderFunctionArgs) => {
- const user = await requireUser(request);
-
- const notifications = await NotificationRepository.findByUserId(user.id, {
- limit: NOTIFICATIONS.PEEK_COUNT,
- });
-
- return { notifications };
-};
diff --git a/app/hooks/swr.ts b/app/hooks/swr.ts
index 5bedba5e5..1af229400 100644
--- a/app/hooks/swr.ts
+++ b/app/hooks/swr.ts
@@ -1,19 +1,15 @@
-import useSWR from "swr";
import useSWRImmutable from "swr/immutable";
import type { EventsWithMapPoolsLoaderData } from "~/features/calendar/routes/map-pool-events";
import type { PatronsListLoaderData } from "~/features/front-page/routes/patrons-list";
-import type { NotificationsLoaderData } from "~/features/notifications/routes/notifications.peek";
import type { TrustersLoaderData } from "~/features/sendouq/routes/trusters";
import type { WeaponUsageLoaderData } from "~/features/sendouq/routes/weapon-usage";
import type { ModeShort, StageId } from "~/modules/in-game-lists";
import {
GET_ALL_EVENTS_WITH_MAP_POOLS_ROUTE,
GET_TRUSTERS_ROUTE,
- NOTIFICATIONS_PEAK_ROUTE,
PATRONS_LIST_ROUTE,
getWeaponUsage,
} from "~/utils/urls";
-import { useUser } from "../features/auth/core/user";
// TODO: replace with useFetcher after proper errr handling is implemented https://github.com/remix-run/react-router/discussions/10013
@@ -83,18 +79,3 @@ export function usePatrons() {
isError: error,
};
}
-
-export function useNotifications() {
- const user = useUser();
- const { data, error, mutate, isValidating } = useSWR(
- user ? NOTIFICATIONS_PEAK_ROUTE : null,
- fetcher(NOTIFICATIONS_PEAK_ROUTE),
- );
-
- return {
- notifications: data?.notifications,
- isLoading: isValidating || (!error && !data),
- isError: error,
- refresh: () => mutate(),
- };
-}
diff --git a/app/root.tsx b/app/root.tsx
index 8dbe63b3f..cf445272e 100644
--- a/app/root.tsx
+++ b/app/root.tsx
@@ -15,7 +15,6 @@ import {
useMatches,
useNavigate,
useNavigation,
- useRevalidator,
useSearchParams,
} from "@remix-run/react";
import generalI18next from "i18next";
@@ -25,6 +24,8 @@ import { I18nProvider } from "react-aria-components";
import { ErrorBoundary as ClientErrorBoundary } from "react-error-boundary";
import { useTranslation } from "react-i18next";
import { useChangeLanguage } from "remix-i18next/react";
+import * as NotificationRepository from "~/features/notifications/NotificationRepository.server";
+import { NOTIFICATIONS } from "~/features/notifications/notifications-contants";
import type { SendouRouteHandle } from "~/utils/remix.server";
import { Catcher } from "./components/Catcher";
import { SendouToastRegion, toastQueue } from "./components/elements/Toast";
@@ -42,7 +43,6 @@ import {
} from "./features/theme/core/provider";
import { getThemeSession } from "./features/theme/core/session.server";
import { useIsMounted } from "./hooks/useIsMounted";
-import { useVisibilityChange } from "./hooks/useVisibilityChange";
import { DEFAULT_LANGUAGE } from "./modules/i18n/config";
import i18next, { i18nCookie } from "./modules/i18n/i18next.server";
import type { Namespace } from "./modules/i18n/resources.server";
@@ -116,6 +116,11 @@ export const loader = async ({ request }: LoaderFunctionArgs) => {
languages: user.languages ? user.languages.split(",") : [],
}
: undefined,
+ notifications: user
+ ? await NotificationRepository.findByUserId(user.id, {
+ limit: NOTIFICATIONS.PEEK_COUNT,
+ })
+ : undefined,
},
{
headers: { "Set-Cookie": await i18nCookie.serialize(locale) },
@@ -263,29 +268,6 @@ function usePreloadTranslation() {
}, []);
}
-// @ts-expect-error to be used in the future
-function useRevalidateOnRevisit() {
- const visibility = useVisibilityChange();
- const { revalidate } = useRevalidator();
- const [lastUpdated, setLastUpdated] = React.useState();
-
- React.useEffect(() => {
- setLastUpdated(new Date());
- }, []);
-
- React.useEffect(() => {
- if (visibility !== "visible" || !lastUpdated) return;
-
- const sinceLastUpdated = new Date().getTime() - lastUpdated.getTime();
-
- // 15 minutes
- if (sinceLastUpdated < 1000 * 60 * 15) return;
-
- setLastUpdated(new Date());
- revalidate();
- }, [visibility, revalidate, lastUpdated]);
-}
-
function useCustomizedCSSVars() {
const matches = useMatches();
diff --git a/app/routes.ts b/app/routes.ts
index dd15705e6..f6bfa0778 100644
--- a/app/routes.ts
+++ b/app/routes.ts
@@ -10,10 +10,6 @@ export default [
route("/patrons-list", "features/front-page/routes/patrons-list.ts"),
route("/notifications", "features/notifications/routes/notifications.tsx"),
- route(
- "/notifications/peek",
- "features/notifications/routes/notifications.peek.ts",
- ),
route(
"/notifications/seen",
"features/notifications/routes/notifications.seen.ts",
diff --git a/app/utils/urls.ts b/app/utils/urls.ts
index 5675503fc..e31fabc13 100644
--- a/app/utils/urls.ts
+++ b/app/utils/urls.ts
@@ -140,7 +140,6 @@ export const GET_TRUSTERS_ROUTE = "/trusters";
export const PATRONS_LIST_ROUTE = "/patrons-list";
export const NOTIFICATIONS_URL = "/notifications";
-export const NOTIFICATIONS_PEAK_ROUTE = "/notifications/peek";
export const NOTIFICATIONS_MARK_AS_SEEN_ROUTE = "/notifications/seen";
interface UserLinkArgs {
diff --git a/locales/en/common.json b/locales/en/common.json
index f2da1340e..6dadc8043 100644
--- a/locales/en/common.json
+++ b/locales/en/common.json
@@ -43,7 +43,6 @@
"notifications.title": "Notifications",
"notifications.empty": "None yet, check back later",
- "notifications.loading": "Loading...",
"notifications.seeAll": "See all",
"notifications.fullList.explanation": "Max of 100 notifications shown. Notifications older than 14 days are automatically deleted.",
"notifications.managePush": "Push notifications",
diff --git a/locales/fr-EU/common.json b/locales/fr-EU/common.json
index 8b771c082..9e9c3f72d 100644
--- a/locales/fr-EU/common.json
+++ b/locales/fr-EU/common.json
@@ -43,7 +43,6 @@
"notifications.title": "Notification",
"notifications.empty": "Rien ici encore, revenez plus tard",
- "notifications.loading": "Chargement...",
"notifications.seeAll": "Voir tout",
"notifications.fullList.explanation": "100 notifications au maximum peuvent être afficher. Les notifications sont effacer automatiquement au bout de 14 jours.",
"notifications.managePush": "Notifications push",
diff --git a/locales/it/common.json b/locales/it/common.json
index e628dc013..0bcc15b2a 100644
--- a/locales/it/common.json
+++ b/locales/it/common.json
@@ -43,7 +43,6 @@
"notifications.title": "Notifiche",
"notifications.empty": "Nessuna notifica, controlla più tardi",
- "notifications.loading": "Caricamento...",
"notifications.seeAll": "Vedi tutte",
"notifications.fullList.explanation": "Un massimo di 100 notifiche sono state mostrate. Le notifiche più vecchie di 14 giorni vengono eliminate automaticamente.",
"notifications.managePush": "Notifiche push",