mirror of
https://github.com/aliasvault/aliasvault.git
synced 2026-04-04 06:52:16 -04:00
Refactor mobile app AsyncStorage usages to shared LocalPreferencesService (#1598)
This commit is contained in:
committed by
Leendert de Borst
parent
7d865d5155
commit
38ce264cd9
@@ -1,5 +1,4 @@
|
||||
import MaterialIcons from '@expo/vector-icons/MaterialIcons';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import * as Haptics from 'expo-haptics';
|
||||
import { useRouter, useLocalSearchParams } from 'expo-router';
|
||||
@@ -36,11 +35,7 @@ import { RobustPressable } from '@/components/ui/RobustPressable';
|
||||
import { SkeletonLoader } from '@/components/ui/SkeletonLoader';
|
||||
import { useApp } from '@/context/AppContext';
|
||||
import { useDb } from '@/context/DbContext';
|
||||
|
||||
/**
|
||||
* Storage key for the show folders preference.
|
||||
*/
|
||||
const SHOW_FOLDERS_STORAGE_KEY = 'items-show-folders';
|
||||
import { LocalPreferencesService } from '@/services/LocalPreferencesService';
|
||||
|
||||
/**
|
||||
* Filter types for the items list.
|
||||
@@ -129,17 +124,15 @@ export default function ItemsScreen(): React.ReactNode {
|
||||
}
|
||||
}, [itemUrl]);
|
||||
|
||||
// Load saved showFolderItems preference from AsyncStorage
|
||||
// Load saved showFolderItems preference from LocalPreferencesService
|
||||
useEffect(() => {
|
||||
/**
|
||||
* Load the show folders preference from AsyncStorage.
|
||||
* Load the show folders preference from LocalPreferencesService.
|
||||
*/
|
||||
const loadShowFoldersPreference = async (): Promise<void> => {
|
||||
try {
|
||||
const stored = await AsyncStorage.getItem(SHOW_FOLDERS_STORAGE_KEY);
|
||||
if (stored !== null) {
|
||||
setShowFolderItems(stored === 'true');
|
||||
}
|
||||
const stored = await LocalPreferencesService.getShowFolders();
|
||||
setShowFolderItems(stored);
|
||||
} catch {
|
||||
// Ignore storage errors, use default value
|
||||
}
|
||||
@@ -826,7 +819,7 @@ export default function ItemsScreen(): React.ReactNode {
|
||||
onPress={() => {
|
||||
const newValue = !showFolderItems;
|
||||
setShowFolderItems(newValue);
|
||||
AsyncStorage.setItem(SHOW_FOLDERS_STORAGE_KEY, String(newValue));
|
||||
LocalPreferencesService.setShowFolders(newValue);
|
||||
}}
|
||||
hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
|
||||
>
|
||||
|
||||
@@ -8,7 +8,7 @@ import { useTranslation } from '@/hooks/useTranslation';
|
||||
import { ThemedContainer } from '@/components/themed/ThemedContainer';
|
||||
import { ThemedScrollView } from '@/components/themed/ThemedScrollView';
|
||||
import { ThemedText } from '@/components/themed/ThemedText';
|
||||
import { useAuth } from '@/context/AuthContext';
|
||||
import { LocalPreferencesService } from '@/services/LocalPreferencesService';
|
||||
import NativeVaultManager from '@/specs/NativeVaultManager';
|
||||
|
||||
/**
|
||||
@@ -25,7 +25,6 @@ export default function ClipboardClearScreen(): React.ReactNode {
|
||||
{ value: 15, label: t('settings.clipboardClearOptions.15seconds') },
|
||||
{ value: 30, label: t('settings.clipboardClearOptions.30seconds') },
|
||||
];
|
||||
const { getClipboardClearTimeout, setClipboardClearTimeout } = useAuth();
|
||||
const [selectedTimeout, setSelectedTimeout] = useState<number>(10);
|
||||
const [isIgnoringBatteryOptimizations, setIsIgnoringBatteryOptimizations] = useState<boolean>(true);
|
||||
const appState = useRef(AppState.currentState);
|
||||
@@ -35,7 +34,7 @@ export default function ClipboardClearScreen(): React.ReactNode {
|
||||
* Load the current clipboard clear timeout.
|
||||
*/
|
||||
const loadCurrentTimeout = async (): Promise<void> => {
|
||||
const timeout = await getClipboardClearTimeout();
|
||||
const timeout = await LocalPreferencesService.getClipboardClearTimeout();
|
||||
setSelectedTimeout(timeout);
|
||||
};
|
||||
|
||||
@@ -72,13 +71,13 @@ export default function ClipboardClearScreen(): React.ReactNode {
|
||||
return (): void => {
|
||||
subscription.remove();
|
||||
};
|
||||
}, [getClipboardClearTimeout]);
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* Handle timeout change.
|
||||
*/
|
||||
const handleTimeoutChange = async (timeout: number): Promise<void> => {
|
||||
await setClipboardClearTimeout(timeout);
|
||||
await LocalPreferencesService.setClipboardClearTimeout(timeout);
|
||||
setSelectedTimeout(timeout);
|
||||
};
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import { TitleContainer } from '@/components/ui/TitleContainer';
|
||||
import { UsernameDisplay } from '@/components/ui/UsernameDisplay';
|
||||
import { useApp } from '@/context/AppContext';
|
||||
import { useDialog } from '@/context/DialogContext';
|
||||
import { LocalPreferencesService } from '@/services/LocalPreferencesService';
|
||||
|
||||
/**
|
||||
* Settings screen.
|
||||
@@ -30,7 +31,7 @@ export default function SettingsScreen() : React.ReactNode {
|
||||
const { showAlert, showConfirm } = useDialog();
|
||||
const insets = useSafeAreaInsets();
|
||||
const { getAuthMethodDisplayKey, shouldShowAutofillReminder } = useApp();
|
||||
const { getAutoLockTimeout, getClipboardClearTimeout } = useApp();
|
||||
const { getAutoLockTimeout } = useApp();
|
||||
const { logoutUserInitiated } = useLogout();
|
||||
const { loadApiUrl, getDisplayUrl } = useApiUrl();
|
||||
const scrollY = useRef(new Animated.Value(0)).current;
|
||||
@@ -74,7 +75,7 @@ export default function SettingsScreen() : React.ReactNode {
|
||||
* Load the clipboard clear display.
|
||||
*/
|
||||
const loadClipboardClearDisplay = async () : Promise<void> => {
|
||||
const clipboardTimeout = await getClipboardClearTimeout();
|
||||
const clipboardTimeout = await LocalPreferencesService.getClipboardClearTimeout();
|
||||
let display = t('common.never');
|
||||
|
||||
if (clipboardTimeout === 5) {
|
||||
@@ -107,7 +108,7 @@ export default function SettingsScreen() : React.ReactNode {
|
||||
};
|
||||
|
||||
loadData();
|
||||
}, [getAutoLockTimeout, getAuthMethodDisplayKey, setIsFirstLoad, loadApiUrl, getClipboardClearTimeout, t])
|
||||
}, [getAutoLockTimeout, getAuthMethodDisplayKey, setIsFirstLoad, loadApiUrl, t])
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@@ -8,8 +8,8 @@ import { copyToClipboardWithExpiration } from '@/utils/ClipboardUtility';
|
||||
|
||||
import { useColors } from '@/hooks/useColorScheme';
|
||||
|
||||
import { useAuth } from '@/context/AuthContext';
|
||||
import { useClipboardCountdown } from '@/context/ClipboardCountdownContext';
|
||||
import { LocalPreferencesService } from '@/services/LocalPreferencesService';
|
||||
|
||||
type FormInputCopyToClipboardProps = {
|
||||
label: string;
|
||||
@@ -31,7 +31,6 @@ const FormInputCopyToClipboard: React.FC<FormInputCopyToClipboardProps> = ({
|
||||
const [isPasswordVisible, setIsPasswordVisible] = useState(false);
|
||||
const colors = useColors();
|
||||
const { t } = useTranslation();
|
||||
const { getClipboardClearTimeout } = useAuth();
|
||||
const { activeFieldId, setActiveField } = useClipboardCountdown();
|
||||
|
||||
const animatedWidth = useRef(new Animated.Value(0)).current;
|
||||
@@ -57,7 +56,7 @@ const FormInputCopyToClipboard: React.FC<FormInputCopyToClipboardProps> = ({
|
||||
animatedWidth.setValue(100);
|
||||
|
||||
// Get timeout and start animation
|
||||
getClipboardClearTimeout().then((timeoutSeconds) => {
|
||||
LocalPreferencesService.getClipboardClearTimeout().then((timeoutSeconds) => {
|
||||
if (!isCancelled && timeoutSeconds > 0 && activeFieldId === fieldId) {
|
||||
animationRef = Animated.timing(animatedWidth, {
|
||||
toValue: 0,
|
||||
@@ -92,7 +91,7 @@ const FormInputCopyToClipboard: React.FC<FormInputCopyToClipboardProps> = ({
|
||||
}
|
||||
animatedWidth.stopAnimation();
|
||||
};
|
||||
}, [isCountingDown, activeFieldId, fieldId, animatedWidth, setActiveField, getClipboardClearTimeout]);
|
||||
}, [isCountingDown, activeFieldId, fieldId, animatedWidth, setActiveField]);
|
||||
|
||||
/**
|
||||
* Copy the value to the clipboard.
|
||||
@@ -101,7 +100,7 @@ const FormInputCopyToClipboard: React.FC<FormInputCopyToClipboardProps> = ({
|
||||
if (value) {
|
||||
try {
|
||||
// Get clipboard clear timeout from settings
|
||||
const timeoutSeconds = await getClipboardClearTimeout();
|
||||
const timeoutSeconds = await LocalPreferencesService.getClipboardClearTimeout();
|
||||
|
||||
// Use centralized clipboard utility
|
||||
await copyToClipboardWithExpiration(value, timeoutSeconds);
|
||||
|
||||
@@ -16,8 +16,8 @@ import { FieldTypes } from '@/utils/dist/core/models/vault';
|
||||
import { useColors } from '@/hooks/useColorScheme';
|
||||
import { useDb } from '@/context/DbContext';
|
||||
import { copyToClipboardWithExpiration } from '@/utils/ClipboardUtility';
|
||||
import { useAuth } from '@/context/AuthContext';
|
||||
import { ModalWrapper } from '@/components/common/ModalWrapper';
|
||||
import { LocalPreferencesService } from '@/services/LocalPreferencesService';
|
||||
import { useVaultMutate } from '@/hooks/useVaultMutate';
|
||||
import { useDialog } from '@/context/DialogContext';
|
||||
|
||||
@@ -49,7 +49,6 @@ const FieldHistoryModal: React.FC<FieldHistoryModalProps> = ({
|
||||
const { t } = useTranslation();
|
||||
const colors = useColors();
|
||||
const dbContext = useDb();
|
||||
const { getClipboardClearTimeout } = useAuth();
|
||||
const { executeVaultMutation } = useVaultMutate();
|
||||
const { showConfirm } = useDialog();
|
||||
const [history, setHistory] = useState<FieldHistory[]>([]);
|
||||
@@ -276,7 +275,7 @@ const FieldHistoryModal: React.FC<FieldHistoryModalProps> = ({
|
||||
|
||||
const handleCopy = async (): Promise<void> => {
|
||||
try {
|
||||
const timeoutSeconds = await getClipboardClearTimeout();
|
||||
const timeoutSeconds = await LocalPreferencesService.getClipboardClearTimeout();
|
||||
await copyToClipboardWithExpiration(value, timeoutSeconds);
|
||||
Toast.show({
|
||||
type: 'success',
|
||||
|
||||
@@ -9,8 +9,8 @@ import type { NativeSyntheticEvent } from 'react-native';
|
||||
import Toast from 'react-native-toast-message';
|
||||
|
||||
import { ItemIcon } from '@/components/items/ItemIcon';
|
||||
import { useAuth } from '@/context/AuthContext';
|
||||
import { useDialog } from '@/context/DialogContext';
|
||||
import { LocalPreferencesService } from '@/services/LocalPreferencesService';
|
||||
import { useColors } from '@/hooks/useColorScheme';
|
||||
import { copyToClipboardWithExpiration } from '@/utils/ClipboardUtility';
|
||||
import type { Item } from '@/utils/dist/core/models/vault';
|
||||
@@ -27,7 +27,6 @@ type ItemCardProps = {
|
||||
export function ItemCard({ item, onItemDelete }: ItemCardProps): React.ReactNode {
|
||||
const colors = useColors();
|
||||
const { t } = useTranslation();
|
||||
const { getClipboardClearTimeout } = useAuth();
|
||||
const { showConfirm } = useDialog();
|
||||
|
||||
/**
|
||||
@@ -68,7 +67,7 @@ export function ItemCard({ item, onItemDelete }: ItemCardProps): React.ReactNode
|
||||
const copyToClipboard = async (text: string): Promise<void> => {
|
||||
try {
|
||||
// Get clipboard clear timeout from settings
|
||||
const timeoutSeconds = await getClipboardClearTimeout();
|
||||
const timeoutSeconds = await LocalPreferencesService.getClipboardClearTimeout();
|
||||
|
||||
// Use centralized clipboard utility
|
||||
await copyToClipboardWithExpiration(text, timeoutSeconds);
|
||||
|
||||
@@ -11,8 +11,8 @@ import { useColors } from '@/hooks/useColorScheme';
|
||||
|
||||
import { ThemedText } from '@/components/themed/ThemedText';
|
||||
import { ThemedView } from '@/components/themed/ThemedView';
|
||||
import { useAuth } from '@/context/AuthContext';
|
||||
import { useDb } from '@/context/DbContext';
|
||||
import { LocalPreferencesService } from '@/services/LocalPreferencesService';
|
||||
|
||||
type TotpSectionProps = {
|
||||
item: Item;
|
||||
@@ -27,7 +27,6 @@ export const TotpSection: React.FC<TotpSectionProps> = ({ item }) : React.ReactN
|
||||
const colors = useColors();
|
||||
const dbContext = useDb();
|
||||
const { t } = useTranslation();
|
||||
const { getClipboardClearTimeout } = useAuth();
|
||||
|
||||
/**
|
||||
* Get the remaining seconds.
|
||||
@@ -74,7 +73,7 @@ export const TotpSection: React.FC<TotpSectionProps> = ({ item }) : React.ReactN
|
||||
const copyToClipboardWithClear = async (code: string): Promise<void> => {
|
||||
try {
|
||||
// Get clipboard clear timeout from settings
|
||||
const timeoutSeconds = await getClipboardClearTimeout();
|
||||
const timeoutSeconds = await LocalPreferencesService.getClipboardClearTimeout();
|
||||
|
||||
// Use centralized clipboard utility
|
||||
await copyToClipboardWithExpiration(code, timeoutSeconds);
|
||||
|
||||
@@ -24,8 +24,6 @@ type AppContextType = {
|
||||
getAuthMethodDisplayKey: () => Promise<string>;
|
||||
getAutoLockTimeout: () => Promise<number>;
|
||||
setAutoLockTimeout: (timeout: number) => Promise<void>;
|
||||
getClipboardClearTimeout: () => Promise<number>;
|
||||
setClipboardClearTimeout: (timeout: number) => Promise<void>;
|
||||
getBiometricDisplayName: () => Promise<string>;
|
||||
isBiometricsEnabledOnDevice: () => Promise<boolean>;
|
||||
setOfflineMode: (isOffline: boolean) => void;
|
||||
@@ -116,8 +114,6 @@ export const AppProvider: React.FC<{ children: React.ReactNode }> = ({ children
|
||||
getAuthMethodDisplayKey: auth.getAuthMethodDisplayKey,
|
||||
getAutoLockTimeout: auth.getAutoLockTimeout,
|
||||
setAutoLockTimeout: auth.setAutoLockTimeout,
|
||||
getClipboardClearTimeout: auth.getClipboardClearTimeout,
|
||||
setClipboardClearTimeout: auth.setClipboardClearTimeout,
|
||||
getBiometricDisplayName: auth.getBiometricDisplayName,
|
||||
isBiometricsEnabledOnDevice: auth.isBiometricsEnabledOnDevice,
|
||||
setOfflineMode: auth.setOfflineMode,
|
||||
@@ -139,8 +135,6 @@ export const AppProvider: React.FC<{ children: React.ReactNode }> = ({ children
|
||||
auth.getAuthMethodDisplayKey,
|
||||
auth.getAutoLockTimeout,
|
||||
auth.setAutoLockTimeout,
|
||||
auth.getClipboardClearTimeout,
|
||||
auth.setClipboardClearTimeout,
|
||||
auth.getBiometricDisplayName,
|
||||
auth.isBiometricsEnabledOnDevice,
|
||||
auth.setOfflineMode,
|
||||
|
||||
@@ -11,6 +11,7 @@ import { useDb } from '@/context/DbContext';
|
||||
import { dialogEventEmitter } from '@/events/DialogEventEmitter';
|
||||
import NativeVaultManager from '@/specs/NativeVaultManager';
|
||||
import i18n from '@/i18n';
|
||||
import { LocalPreferencesService } from '@/services/LocalPreferencesService';
|
||||
|
||||
// Create a navigation reference
|
||||
export const navigationRef = React.createRef<NavigationContainerRef<ParamListBase>>();
|
||||
@@ -41,8 +42,6 @@ type AuthContextType = {
|
||||
getAuthMethodDisplayKey: () => Promise<string>;
|
||||
getAutoLockTimeout: () => Promise<number>;
|
||||
setAutoLockTimeout: (timeout: number) => Promise<void>;
|
||||
getClipboardClearTimeout: () => Promise<number>;
|
||||
setClipboardClearTimeout: (timeout: number) => Promise<void>;
|
||||
getBiometricDisplayName: () => Promise<string>;
|
||||
isBiometricsEnabledOnDevice: () => Promise<boolean>;
|
||||
setOfflineMode: (isOffline: boolean) => void;
|
||||
@@ -53,8 +52,6 @@ type AuthContextType = {
|
||||
markAutofillConfigured: () => Promise<void>;
|
||||
}
|
||||
|
||||
const AUTOFILL_CONFIGURED_KEY = 'autofill_configured';
|
||||
const CLIPBOARD_TIMEOUT_KEY = 'clipboard_clear_timeout';
|
||||
|
||||
/**
|
||||
* Auth context.
|
||||
@@ -351,30 +348,6 @@ export const AuthProvider: React.FC<{
|
||||
}
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* Get the clipboard clear timeout from AsyncStorage
|
||||
*/
|
||||
const getClipboardClearTimeout = useCallback(async (): Promise<number> => {
|
||||
try {
|
||||
const timeoutStr = await AsyncStorage.getItem(CLIPBOARD_TIMEOUT_KEY);
|
||||
return timeoutStr ? parseInt(timeoutStr, 10) : 15;
|
||||
} catch (error) {
|
||||
console.error('Failed to get clipboard clear timeout:', error);
|
||||
return 10;
|
||||
}
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* Set the clipboard clear timeout in AsyncStorage
|
||||
*/
|
||||
const setClipboardClearTimeout = useCallback(async (timeout: number): Promise<void> => {
|
||||
try {
|
||||
await AsyncStorage.setItem(CLIPBOARD_TIMEOUT_KEY, timeout.toString());
|
||||
} catch (error) {
|
||||
console.error('Failed to set clipboard clear timeout:', error);
|
||||
}
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* Get the encryption key derivation parameters from native storage.
|
||||
* Returns parsed parameters or null if not available.
|
||||
@@ -429,15 +402,15 @@ export const AuthProvider: React.FC<{
|
||||
* Load autofill state from storage
|
||||
*/
|
||||
const loadAutofillState = useCallback(async () => {
|
||||
const configured = await AsyncStorage.getItem(AUTOFILL_CONFIGURED_KEY);
|
||||
setShouldShowAutofillReminder(configured !== 'true');
|
||||
const configured = await LocalPreferencesService.getAutofillConfigured();
|
||||
setShouldShowAutofillReminder(!configured);
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* Mark autofill as configured for the current platform
|
||||
*/
|
||||
const markAutofillConfigured = useCallback(async () => {
|
||||
await AsyncStorage.setItem(AUTOFILL_CONFIGURED_KEY, 'true');
|
||||
await LocalPreferencesService.setAutofillConfigured(true);
|
||||
setShouldShowAutofillReminder(false);
|
||||
}, []);
|
||||
|
||||
@@ -472,8 +445,6 @@ export const AuthProvider: React.FC<{
|
||||
isBiometricsEnabledOnDevice,
|
||||
getAutoLockTimeout,
|
||||
setAutoLockTimeout,
|
||||
getClipboardClearTimeout,
|
||||
setClipboardClearTimeout,
|
||||
getBiometricDisplayName,
|
||||
markAutofillConfigured,
|
||||
verifyPassword,
|
||||
@@ -497,8 +468,6 @@ export const AuthProvider: React.FC<{
|
||||
isBiometricsEnabledOnDevice,
|
||||
getAutoLockTimeout,
|
||||
setAutoLockTimeout,
|
||||
getClipboardClearTimeout,
|
||||
setClipboardClearTimeout,
|
||||
getBiometricDisplayName,
|
||||
markAutofillConfigured,
|
||||
verifyPassword,
|
||||
|
||||
94
apps/mobile-app/services/LocalPreferencesService.ts
Normal file
94
apps/mobile-app/services/LocalPreferencesService.ts
Normal file
@@ -0,0 +1,94 @@
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
|
||||
/**
|
||||
* Storage keys for local preferences.
|
||||
* These are defined inline since they're only used by this service.
|
||||
*/
|
||||
const KEYS = {
|
||||
// Autofill configuration
|
||||
AUTOFILL_CONFIGURED: 'autofill_configured',
|
||||
|
||||
// Timeouts
|
||||
CLIPBOARD_CLEAR_TIMEOUT: 'clipboard_clear_timeout',
|
||||
|
||||
// UI preferences
|
||||
SHOW_FOLDERS: 'items-show-folders',
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* Service for managing user preferences that are stored locally (not in the vault).
|
||||
* Provides typed getters/setters with sensible defaults for all local storage settings.
|
||||
*
|
||||
* Note: This service handles UI preferences stored in AsyncStorage.
|
||||
* Security-sensitive settings (auth tokens, vault data) are handled by the native layer.
|
||||
*/
|
||||
export const LocalPreferencesService = {
|
||||
/**
|
||||
* Get whether autofill has been configured by the user.
|
||||
* @returns Whether autofill has been configured. Defaults to false.
|
||||
*/
|
||||
async getAutofillConfigured(): Promise<boolean> {
|
||||
const value = await AsyncStorage.getItem(KEYS.AUTOFILL_CONFIGURED);
|
||||
return value === 'true';
|
||||
},
|
||||
|
||||
/**
|
||||
* Set whether autofill has been configured.
|
||||
*/
|
||||
async setAutofillConfigured(configured: boolean): Promise<void> {
|
||||
await AsyncStorage.setItem(KEYS.AUTOFILL_CONFIGURED, configured.toString());
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the clipboard clear timeout in seconds.
|
||||
* @returns Timeout in seconds. Defaults to 15.
|
||||
*/
|
||||
async getClipboardClearTimeout(): Promise<number> {
|
||||
const value = await AsyncStorage.getItem(KEYS.CLIPBOARD_CLEAR_TIMEOUT);
|
||||
return value ? parseInt(value, 10) : 15;
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the clipboard clear timeout in seconds.
|
||||
*/
|
||||
async setClipboardClearTimeout(timeout: number): Promise<void> {
|
||||
await AsyncStorage.setItem(KEYS.CLIPBOARD_CLEAR_TIMEOUT, timeout.toString());
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the show folders preference.
|
||||
* @returns Whether to show folders (true) or show all items flat (false). Defaults to true.
|
||||
*/
|
||||
async getShowFolders(): Promise<boolean> {
|
||||
const value = await AsyncStorage.getItem(KEYS.SHOW_FOLDERS);
|
||||
// Default to true if not set
|
||||
return value === null ? true : value === 'true';
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the show folders preference.
|
||||
*/
|
||||
async setShowFolders(showFolders: boolean): Promise<void> {
|
||||
await AsyncStorage.setItem(KEYS.SHOW_FOLDERS, showFolders.toString());
|
||||
},
|
||||
|
||||
/**
|
||||
* Clear all UI preferences. Can be called on logout.
|
||||
* Note: This only clears UI preferences, not security-related settings.
|
||||
*/
|
||||
async clearUiPreferences(): Promise<void> {
|
||||
await AsyncStorage.removeItem(KEYS.SHOW_FOLDERS);
|
||||
},
|
||||
|
||||
/**
|
||||
* Clear all preferences. Called on logout to reset everything.
|
||||
* Note: Security settings are handled by the native layer.
|
||||
*/
|
||||
async clearAll(): Promise<void> {
|
||||
await Promise.all([
|
||||
AsyncStorage.removeItem(KEYS.AUTOFILL_CONFIGURED),
|
||||
AsyncStorage.removeItem(KEYS.CLIPBOARD_CLEAR_TIMEOUT),
|
||||
AsyncStorage.removeItem(KEYS.SHOW_FOLDERS),
|
||||
]);
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user