Build complete Expo/React Native mobile app with: - Auth flow: email/password login, registration, biometric auth - Dashboard: exposure summary, spam stats, voice protection status - DarkWatch: watch list management, exposure feed, alert toggles - SpamShield: call/text history, whitelist/blacklist management - VoicePrint: family member enrollment, voice analysis - Settings: tier management, notification preferences, security - Push notification integration via FCM/APNs - Offline-first state management with Zustand + AsyncStorage - Integration with @shieldai/mobile-api-client for API services - React Navigation with auth-aware routing (stack + bottom tabs) - Dark theme with consistent design system (colors, spacing, typography) - Network status monitoring and offline request queuing Co-Authored-By: Paperclip <noreply@paperclip.ing>
59 lines
1.6 KiB
TypeScript
59 lines
1.6 KiB
TypeScript
import { create } from 'zustand';
|
|
import { persist, createJSONStorage } from 'zustand/middleware';
|
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
import type { SpamRecord } from '@/types';
|
|
|
|
type PhoneList = { number: string; label: string }[];
|
|
|
|
interface SpamShieldState {
|
|
callHistory: SpamRecord[];
|
|
textHistory: SpamRecord[];
|
|
whitelist: PhoneList;
|
|
blacklist: PhoneList;
|
|
isLoading: false;
|
|
addToWhitelist: (number: string, label: string) => void;
|
|
addToBlacklist: (number: string, label: string) => void;
|
|
removeFromWhitelist: (number: string) => void;
|
|
removeFromBlacklist: (number: string) => void;
|
|
}
|
|
|
|
export const useSpamShieldStore = create<SpamShieldState>()(
|
|
persist(
|
|
(set) => ({
|
|
callHistory: [],
|
|
textHistory: [],
|
|
whitelist: [],
|
|
blacklist: [],
|
|
isLoading: false,
|
|
|
|
addToWhitelist: (number, label) => {
|
|
set((state) => ({
|
|
whitelist: [...state.whitelist, { number, label }],
|
|
}));
|
|
},
|
|
|
|
addToBlacklist: (number, label) => {
|
|
set((state) => ({
|
|
blacklist: [...state.blacklist, { number, label }],
|
|
}));
|
|
},
|
|
|
|
removeFromWhitelist: (number) => {
|
|
set((state) => ({
|
|
whitelist: state.whitelist.filter((item) => item.number !== number),
|
|
}));
|
|
},
|
|
|
|
removeFromBlacklist: (number) => {
|
|
set((state) => ({
|
|
blacklist: state.blacklist.filter((item) => item.number !== number),
|
|
}));
|
|
},
|
|
}),
|
|
{
|
|
name: '@shieldai_spamshield',
|
|
storage: createJSONStorage(() => AsyncStorage),
|
|
}
|
|
)
|
|
);
|