Skip to content
13 changes: 13 additions & 0 deletions apps/web/src/appSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ const BUILT_IN_MODEL_SLUGS_BY_PROVIDER: Record<ProviderKind, ReadonlySet<string>
codex: new Set(getModelOptions("codex").map((option) => option.slug)),
};

export enum NotificationLevel {
Off = "off",
Important = "important",
Normal = "normal",
Verbose = "verbose",
}

const AppSettingsSchema = Schema.Struct({
codexBinaryPath: Schema.String.check(Schema.isMaxLength(4096)).pipe(
Schema.withConstructorDefault(() => Option.some("")),
Expand All @@ -31,6 +38,12 @@ const AppSettingsSchema = Schema.Struct({
timestampFormat: Schema.Literals(["locale", "12-hour", "24-hour"]).pipe(
Schema.withConstructorDefault(() => Option.some(DEFAULT_TIMESTAMP_FORMAT)),
),
notificationLevel: Schema.Literals([
NotificationLevel.Off,
NotificationLevel.Important,
NotificationLevel.Normal,
NotificationLevel.Verbose,
]).pipe(Schema.withConstructorDefault(() => Option.some(NotificationLevel.Normal))),
customCodexModels: Schema.Array(Schema.String).pipe(
Schema.withConstructorDefault(() => Option.some([])),
),
Expand Down
30 changes: 30 additions & 0 deletions apps/web/src/hooks/useNotification.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { useCallback, useEffect, useState } from "react";

import {
getNotificationPermission,
requestNotificationPermission,
} from "../lib/nativeNotifications";

export function useNotification() {
const [permission, setPermission] = useState(getNotificationPermission());

const refresh = useCallback(() => {
setPermission(getNotificationPermission());
}, []);

const requestPermission = useCallback(async () => {
const next = await requestNotificationPermission();
setPermission(next);
}, []);

useEffect(() => {
refresh();
window.addEventListener("focus", refresh);

return () => {
window.removeEventListener("focus", refresh);
};
}, [refresh]);

return { permission, requestPermission, refresh };
}
Loading