Open History to see the last commit
1import { useAtomValue } from "@effect/atom-react";
2import { Atom } from "effect/reactivity";
3import * as Linking from "expo-linking";
4import { useEffect } from "react";
5import { Platform } from "react-native";
6import { useAppearancePreferences } from "../features/settings/appearance/AppearancePreferencesProvider";
7import { environmentCatalog } from "../connection/catalog";
8import { environmentPresentations } from "../state/presentation";
9import { publishSubscriptionUsage } from "./publishSubscriptionUsage";
10import { buildSubscriptionUsageSnapshot } from "./subscriptionUsageSnapshot";
11import { createWidgetTheme } from "./widgetTheme";
12
13// Isolate quota changes from the much busier thread/config presentation stream.
14const snapshotAtom = Atom.make((get) =>
15 buildSubscriptionUsageSnapshot(
16 get(environmentPresentations.presentationsWithProvidersAtom),
17 Linking.createURL("settings/usage", { queryParams: { tab: "limits" } }),
18 Platform.OS === "android" ? Infinity : 6,
19 ),
20).pipe(Atom.withEquality((a, b) => JSON.stringify(a) === JSON.stringify(b)));
21
22export function SubscriptionUsageCoordinator() {
23 const {
24 themeMode,
25 themeAppearance,
26 themeVariablesByAppearance,
27 isReady: appearanceReady,
28 } = useAppearancePreferences();
29 const catalog = useAtomValue(environmentCatalog.catalogValueAtom);
30 const snapshot = useAtomValue(snapshotAtom);
31 const androidAppearance = Platform.OS === "android" ? themeAppearance : null;
32 // oxlint-disable-next-line t3code/no-unreasoned-state-sync -- publishes subscription usage and theme to the native home screen widget
33 useEffect(() => {
34 if (!catalog.isReady || !appearanceReady) return;
35 void Promise.resolve()
36 .then(() =>
37 publishSubscriptionUsage({
38 ...snapshot,
39 theme: createWidgetTheme(themeMode, themeVariablesByAppearance),
40 }),
41 )
42 .catch((error: unknown) => {
43 console.warn("Could not update subscription usage widget", error);
44 });
45 }, [
46 catalog.isReady,
47 appearanceReady,
48 snapshot,
49 themeMode,
50 themeVariablesByAppearance,
51 // oxlint-disable-next-line react/exhaustive-effect-dependencies -- Android stores resolved colors; System appearance changes must republish them.
52 androidAppearance,
53 ]);
54 return null;
55}