103 lines
3.6 KiB
TypeScript
103 lines
3.6 KiB
TypeScript
import * as SecureStore from "expo-secure-store";
|
|
|
|
const KEYS = {
|
|
CODEX_AUTH: "codexbar_codex_auth",
|
|
CLAUDE_SESSION_KEY: "codexbar_claude_session_key",
|
|
CLAUDE_LAST_ACTIVE_ORG: "codexbar_claude_last_active_org",
|
|
NOTIF_DAILY_ENABLED: "notifDailyEnabled",
|
|
NOTIF_DAILY_HOUR: "notifDailyHour",
|
|
NOTIF_DAILY_MINUTE: "notifDailyMinute",
|
|
NOTIF_THRESHOLD_ENABLED: "notifThresholdEnabled",
|
|
NOTIF_THRESHOLD_PCT: "notifThresholdPct",
|
|
NOTIF_THRESHOLD_LAST_FIRED: "notifThresholdLastFired",
|
|
} as const;
|
|
|
|
export interface NotifSettings {
|
|
dailyEnabled: boolean;
|
|
dailyHour: number;
|
|
dailyMinute: number;
|
|
thresholdEnabled: boolean;
|
|
/** Alert when remaining quota falls below this % (e.g. 20 = fire when < 20% left) */
|
|
thresholdPct: number;
|
|
}
|
|
|
|
export async function loadNotifSettings(): Promise<NotifSettings> {
|
|
const [de, dh, dm, te, tp] = await Promise.all([
|
|
SecureStore.getItemAsync(KEYS.NOTIF_DAILY_ENABLED),
|
|
SecureStore.getItemAsync(KEYS.NOTIF_DAILY_HOUR),
|
|
SecureStore.getItemAsync(KEYS.NOTIF_DAILY_MINUTE),
|
|
SecureStore.getItemAsync(KEYS.NOTIF_THRESHOLD_ENABLED),
|
|
SecureStore.getItemAsync(KEYS.NOTIF_THRESHOLD_PCT),
|
|
]);
|
|
return {
|
|
dailyEnabled: de === "true",
|
|
dailyHour: dh !== null ? parseInt(dh, 10) : 9,
|
|
dailyMinute: dm !== null ? parseInt(dm, 10) : 0,
|
|
thresholdEnabled: te === "true",
|
|
thresholdPct: tp !== null ? parseInt(tp, 10) : 20,
|
|
};
|
|
}
|
|
|
|
export async function saveNotifSettings(s: NotifSettings): Promise<void> {
|
|
await Promise.all([
|
|
SecureStore.setItemAsync(KEYS.NOTIF_DAILY_ENABLED, String(s.dailyEnabled)),
|
|
SecureStore.setItemAsync(KEYS.NOTIF_DAILY_HOUR, String(s.dailyHour)),
|
|
SecureStore.setItemAsync(KEYS.NOTIF_DAILY_MINUTE, String(s.dailyMinute)),
|
|
SecureStore.setItemAsync(KEYS.NOTIF_THRESHOLD_ENABLED, String(s.thresholdEnabled)),
|
|
SecureStore.setItemAsync(KEYS.NOTIF_THRESHOLD_PCT, String(s.thresholdPct)),
|
|
]);
|
|
}
|
|
|
|
export async function loadNotifThresholdLastFired(): Promise<string | null> {
|
|
return SecureStore.getItemAsync(KEYS.NOTIF_THRESHOLD_LAST_FIRED);
|
|
}
|
|
|
|
export async function saveNotifThresholdLastFired(date: string): Promise<void> {
|
|
await SecureStore.setItemAsync(KEYS.NOTIF_THRESHOLD_LAST_FIRED, date);
|
|
}
|
|
|
|
export async function saveCodexAuth(auth: {
|
|
accessToken: string;
|
|
accountId?: string;
|
|
}): Promise<void> {
|
|
await SecureStore.setItemAsync(KEYS.CODEX_AUTH, JSON.stringify(auth));
|
|
}
|
|
|
|
export async function loadCodexAuth(): Promise<{
|
|
accessToken: string;
|
|
accountId?: string;
|
|
} | null> {
|
|
const raw = await SecureStore.getItemAsync(KEYS.CODEX_AUTH);
|
|
if (!raw) return null;
|
|
return JSON.parse(raw) as { accessToken: string; accountId?: string };
|
|
}
|
|
|
|
export async function saveClaudeSessionKey(key: string): Promise<void> {
|
|
await SecureStore.setItemAsync(KEYS.CLAUDE_SESSION_KEY, key);
|
|
}
|
|
|
|
export async function loadClaudeSessionKey(): Promise<string | null> {
|
|
return SecureStore.getItemAsync(KEYS.CLAUDE_SESSION_KEY);
|
|
}
|
|
|
|
export async function saveClaudeLastActiveOrg(orgId: string): Promise<void> {
|
|
await SecureStore.setItemAsync(KEYS.CLAUDE_LAST_ACTIVE_ORG, orgId);
|
|
}
|
|
|
|
export async function loadClaudeLastActiveOrg(): Promise<string | null> {
|
|
return SecureStore.getItemAsync(KEYS.CLAUDE_LAST_ACTIVE_ORG);
|
|
}
|
|
|
|
export async function clearClaudeLastActiveOrg(): Promise<void> {
|
|
await SecureStore.deleteItemAsync(KEYS.CLAUDE_LAST_ACTIVE_ORG);
|
|
}
|
|
|
|
export async function clearCodexAuth(): Promise<void> {
|
|
await SecureStore.deleteItemAsync(KEYS.CODEX_AUTH);
|
|
}
|
|
|
|
export async function clearClaudeSessionKey(): Promise<void> {
|
|
await SecureStore.deleteItemAsync(KEYS.CLAUDE_SESSION_KEY);
|
|
await SecureStore.deleteItemAsync(KEYS.CLAUDE_LAST_ACTIVE_ORG);
|
|
}
|