144 lines
4.7 KiB
TypeScript
144 lines
4.7 KiB
TypeScript
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
|
|
/**
|
|
* 本地存储 key 统一管理,避免 UI 里散落硬编码
|
|
*/
|
|
const KEY_ONBOARDING_COMPLETED = 'onboarding.completed';
|
|
const KEY_PUSH_PROMPT_STATE = 'push.promptState';
|
|
const KEY_CONTENT_REACTIONS = 'content.reactions';
|
|
const KEY_FAVORITES_ITEMS = 'favorites.items';
|
|
const KEY_CONSENT_ACCEPTED = 'consent.accepted';
|
|
const KEY_USER_PROFILE = 'user.profile';
|
|
const KEY_UI_THEME_MODE = 'ui.theme.mode';
|
|
const KEY_DAILY_REMINDER_SETTINGS = 'dailyReminder.settings';
|
|
|
|
export type PushPromptState = 'enabled' | 'skipped' | 'unknown';
|
|
export type Reaction = 'like' | 'dislike';
|
|
export type ReactionsMap = Record<string, Reaction>;
|
|
export type ThemeMode = 'scenery' | 'color';
|
|
export type UserProfile = {
|
|
name?: string;
|
|
intents?: string[];
|
|
};
|
|
export type DailyReminderSettings = {
|
|
timesPerDay: number;
|
|
pushEnabled: boolean;
|
|
};
|
|
|
|
|
|
async function getJson<T>(key: string, fallback: T): Promise<T> {
|
|
const raw = await AsyncStorage.getItem(key);
|
|
if (!raw) return fallback;
|
|
try {
|
|
return JSON.parse(raw) as T;
|
|
} catch {
|
|
return fallback;
|
|
}
|
|
}
|
|
|
|
async function setJson<T>(key: string, value: T): Promise<void> {
|
|
await AsyncStorage.setItem(key, JSON.stringify(value));
|
|
}
|
|
|
|
export async function getOnboardingCompleted(): Promise<boolean> {
|
|
const raw = await AsyncStorage.getItem(KEY_ONBOARDING_COMPLETED);
|
|
return raw === 'true';
|
|
}
|
|
|
|
export async function setOnboardingCompleted(completed: boolean): Promise<void> {
|
|
await AsyncStorage.setItem(KEY_ONBOARDING_COMPLETED, completed ? 'true' : 'false');
|
|
}
|
|
|
|
export async function getPushPromptState(): Promise<PushPromptState> {
|
|
const raw = await AsyncStorage.getItem(KEY_PUSH_PROMPT_STATE);
|
|
if (raw === 'enabled' || raw === 'skipped' || raw === 'unknown') return raw;
|
|
return 'unknown';
|
|
}
|
|
|
|
export async function setPushPromptState(state: PushPromptState): Promise<void> {
|
|
await AsyncStorage.setItem(KEY_PUSH_PROMPT_STATE, state);
|
|
}
|
|
|
|
export async function getReactions(): Promise<ReactionsMap> {
|
|
return await getJson<ReactionsMap>(KEY_CONTENT_REACTIONS, {});
|
|
}
|
|
|
|
export async function setReaction(contentId: string, reaction: Reaction): Promise<void> {
|
|
const next = await getReactions();
|
|
next[contentId] = reaction;
|
|
await setJson(KEY_CONTENT_REACTIONS, next);
|
|
}
|
|
|
|
export type FavoriteItem = {
|
|
id: string;
|
|
date: string;
|
|
themeMode: ThemeMode;
|
|
background: string; // 颜色值或图片路径
|
|
};
|
|
|
|
export async function getFavorites(): Promise<FavoriteItem[]> {
|
|
return await getJson<FavoriteItem[]>(KEY_FAVORITES_ITEMS, []);
|
|
}
|
|
|
|
export async function addFavorite(item: FavoriteItem): Promise<void> {
|
|
const list = await getFavorites();
|
|
if (list.some(i => i.id === item.id)) return;
|
|
const newList = [item, ...list];
|
|
console.log('Adding to favorites, new list size:', newList.length);
|
|
await setJson(KEY_FAVORITES_ITEMS, newList);
|
|
}
|
|
|
|
export async function removeFavorite(contentId: string): Promise<void> {
|
|
const list = await getFavorites();
|
|
const next = list.filter(item => item.id !== contentId);
|
|
await setJson(KEY_FAVORITES_ITEMS, next);
|
|
}
|
|
|
|
export async function getConsentAccepted(): Promise<boolean> {
|
|
const raw = await AsyncStorage.getItem(KEY_CONSENT_ACCEPTED);
|
|
return raw === 'true';
|
|
}
|
|
|
|
export async function setConsentAccepted(accepted: boolean): Promise<void> {
|
|
await AsyncStorage.setItem(KEY_CONSENT_ACCEPTED, accepted ? 'true' : 'false');
|
|
}
|
|
|
|
export async function getThemeMode(): Promise<ThemeMode> {
|
|
const raw = await AsyncStorage.getItem(KEY_UI_THEME_MODE);
|
|
if (raw === 'scenery' || raw === 'color') return raw;
|
|
return 'scenery';
|
|
}
|
|
|
|
export async function setThemeMode(mode: ThemeMode): Promise<void> {
|
|
await AsyncStorage.setItem(KEY_UI_THEME_MODE, mode);
|
|
}
|
|
|
|
export async function getUserProfile(): Promise<UserProfile> {
|
|
return await getJson<UserProfile>(KEY_USER_PROFILE, {});
|
|
}
|
|
|
|
export async function setUserProfile(profile: UserProfile): Promise<void> {
|
|
const current = await getUserProfile();
|
|
await setJson(KEY_USER_PROFILE, { ...current, ...profile });
|
|
}
|
|
|
|
export async function getDailyReminderSettings(): Promise<DailyReminderSettings> {
|
|
const s = await getJson<DailyReminderSettings>(KEY_DAILY_REMINDER_SETTINGS, {
|
|
timesPerDay: 3,
|
|
pushEnabled: false,
|
|
});
|
|
const timesPerDay = Number.isFinite(s.timesPerDay) ? s.timesPerDay : 3;
|
|
return {
|
|
timesPerDay: Math.min(10, Math.max(1, Math.round(timesPerDay))),
|
|
pushEnabled: Boolean(s.pushEnabled),
|
|
};
|
|
}
|
|
|
|
export async function setDailyReminderSettings(settings: DailyReminderSettings): Promise<void> {
|
|
const timesPerDay = Math.min(10, Math.max(1, Math.round(settings.timesPerDay)));
|
|
await setJson(KEY_DAILY_REMINDER_SETTINGS, {
|
|
timesPerDay,
|
|
pushEnabled: Boolean(settings.pushEnabled),
|
|
});
|
|
}
|