mirror of
https://github.com/movie-web/native-app.git
synced 2025-09-13 17:13:25 +00:00
feat: settings storage & theme persistence
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
"@movie-web/provider-utils": "*",
|
||||
"@movie-web/tmdb": "*",
|
||||
"@react-native-anywhere/polyfill-base64": "0.0.1-alpha.0",
|
||||
"@react-native-async-storage/async-storage": "1.21.0",
|
||||
"@react-navigation/native": "^6.1.9",
|
||||
"@tamagui/animations-moti": "^1.91.4",
|
||||
"@tamagui/babel-plugin": "^1.91.4",
|
||||
|
33
apps/expo/src/settings/index.ts
Normal file
33
apps/expo/src/settings/index.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import AsyncStorage from "@react-native-async-storage/async-storage";
|
||||
|
||||
import type { ThemeStoreOption } from "~/stores/theme";
|
||||
|
||||
interface ThemeSettings {
|
||||
theme: ThemeStoreOption;
|
||||
}
|
||||
|
||||
interface Settings {
|
||||
themes: ThemeSettings;
|
||||
}
|
||||
|
||||
const settingsKey = "settings";
|
||||
|
||||
const saveSettings = async (settings: Settings) => {
|
||||
await AsyncStorage.setItem(settingsKey, JSON.stringify(settings));
|
||||
};
|
||||
|
||||
const loadSettings = async (): Promise<Settings | null> => {
|
||||
const json = await AsyncStorage.getItem(settingsKey);
|
||||
return json ? (JSON.parse(json) as Settings) : null;
|
||||
};
|
||||
|
||||
export const getTheme = async (): Promise<ThemeStoreOption> => {
|
||||
const settings = await loadSettings();
|
||||
return settings?.themes?.theme ?? "main";
|
||||
};
|
||||
|
||||
export const saveTheme = async (newTheme: ThemeStoreOption) => {
|
||||
const settings = (await loadSettings()) ?? { themes: { theme: newTheme } };
|
||||
settings.themes.theme = newTheme;
|
||||
await saveSettings(settings);
|
||||
};
|
@@ -2,6 +2,8 @@ import { setAppIcon } from "expo-dynamic-app-icon";
|
||||
import { create } from "zustand";
|
||||
import { immer } from "zustand/middleware/immer";
|
||||
|
||||
import { getTheme, saveTheme } from "~/settings";
|
||||
|
||||
export type ThemeStoreOption = "main" | "blue" | "gray" | "red" | "teal";
|
||||
|
||||
export interface ThemeStore {
|
||||
@@ -10,13 +12,28 @@ export interface ThemeStore {
|
||||
}
|
||||
|
||||
export const useThemeStore = create(
|
||||
immer<ThemeStore>((set) => ({
|
||||
theme: "main",
|
||||
setTheme(v) {
|
||||
immer<ThemeStore>((set) => {
|
||||
void getTheme().then((savedTheme) => {
|
||||
set((s) => {
|
||||
s.theme = v;
|
||||
setAppIcon(v);
|
||||
s.theme = savedTheme;
|
||||
});
|
||||
},
|
||||
})),
|
||||
});
|
||||
|
||||
return {
|
||||
theme: "main",
|
||||
setTheme: (newTheme) => {
|
||||
setAppIcon(newTheme);
|
||||
|
||||
saveTheme(newTheme)
|
||||
.then(() => {
|
||||
set((s) => {
|
||||
s.theme = newTheme;
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Failed to save theme:", error);
|
||||
});
|
||||
},
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
Reference in New Issue
Block a user