fix the warning

This commit is contained in:
Ada
2026-01-30 15:22:13 -08:00
parent 749ed2f05a
commit c07f1f20d5

View File

@@ -23,6 +23,7 @@ import { colors, typography, spacing, borderRadius, shadows } from '../theme/col
import { SystemStatus, KillSwitchLog } from '../types'; import { SystemStatus, KillSwitchLog } from '../types';
import VaultScreen from './VaultScreen'; import VaultScreen from './VaultScreen';
// Nautical-themed mnemonic word list (unique words only)
const MNEMONIC_WORDS = [ const MNEMONIC_WORDS = [
'anchor', 'harbor', 'compass', 'lighthouse', 'current', 'ocean', 'tide', 'voyage', 'anchor', 'harbor', 'compass', 'lighthouse', 'current', 'ocean', 'tide', 'voyage',
'keel', 'stern', 'bow', 'mast', 'sail', 'port', 'starboard', 'reef', 'keel', 'stern', 'bow', 'mast', 'sail', 'port', 'starboard', 'reef',
@@ -30,9 +31,17 @@ const MNEMONIC_WORDS = [
'horizon', 'sextant', 'sound', 'drift', 'wake', 'mariner', 'pilot', 'fathom', 'horizon', 'sextant', 'sound', 'drift', 'wake', 'mariner', 'pilot', 'fathom',
'buoy', 'lantern', 'harpoon', 'lagoon', 'bay', 'strait', 'riptide', 'foam', 'buoy', 'lantern', 'harpoon', 'lagoon', 'bay', 'strait', 'riptide', 'foam',
'coral', 'pearl', 'trident', 'ebb', 'flow', 'vault', 'cipher', 'shroud', 'coral', 'pearl', 'trident', 'ebb', 'flow', 'vault', 'cipher', 'shroud',
'salt', 'wave', 'grotto', 'lagoon', 'storm', 'north', 'south', 'east', 'salt', 'wave', 'grotto', 'storm', 'north', 'south', 'east', 'west',
'west', 'ember', 'cabin', 'signal', 'ledger', 'torch', 'sanctum', 'oath', 'ember', 'cabin', 'ledger', 'torch', 'sanctum', 'oath', 'depths', 'captain',
]; ] as const;
// Animation timing constants
const ANIMATION_DURATION = {
pulse: 1200,
glow: 1500,
rotate: 30000,
heartbeatPress: 150,
} as const;
const generateMnemonic = (wordCount = 12) => { const generateMnemonic = (wordCount = 12) => {
const words: string[] = []; const words: string[] = [];
@@ -49,11 +58,14 @@ const splitMnemonic = (words: string[]) => [
words.slice(8, 12), words.slice(8, 12),
]; ];
// Icon names type for type safety
type StatusIconName = 'checkmark-circle' | 'warning' | 'alert-circle';
// Status configuration with nautical theme // Status configuration with nautical theme
const statusConfig: Record<SystemStatus, { const statusConfig: Record<SystemStatus, {
color: string; color: string;
label: string; label: string;
icon: string; icon: StatusIconName;
description: string; description: string;
gradientColors: [string, string]; gradientColors: [string, string];
}> = { }> = {
@@ -123,46 +135,56 @@ export default function SentinelScreen() {
useEffect(() => { useEffect(() => {
// Pulse animation // Pulse animation
Animated.loop( const pulseAnimation = Animated.loop(
Animated.sequence([ Animated.sequence([
Animated.timing(pulseAnim, { Animated.timing(pulseAnim, {
toValue: 1.06, toValue: 1.06,
duration: 1200, duration: ANIMATION_DURATION.pulse,
useNativeDriver: true, useNativeDriver: true,
}), }),
Animated.timing(pulseAnim, { Animated.timing(pulseAnim, {
toValue: 1, toValue: 1,
duration: 1200, duration: ANIMATION_DURATION.pulse,
useNativeDriver: true, useNativeDriver: true,
}), }),
]) ])
).start(); );
pulseAnimation.start();
// Glow animation // Glow animation
Animated.loop( const glowAnimation = Animated.loop(
Animated.sequence([ Animated.sequence([
Animated.timing(glowAnim, { Animated.timing(glowAnim, {
toValue: 1, toValue: 1,
duration: 1500, duration: ANIMATION_DURATION.glow,
useNativeDriver: true, useNativeDriver: true,
}), }),
Animated.timing(glowAnim, { Animated.timing(glowAnim, {
toValue: 0.5, toValue: 0.5,
duration: 1500, duration: ANIMATION_DURATION.glow,
useNativeDriver: true, useNativeDriver: true,
}), }),
]) ])
).start(); );
glowAnimation.start();
// Slow rotate for ship wheel // Slow rotate for ship wheel
Animated.loop( const rotateAnimation = Animated.loop(
Animated.timing(rotateAnim, { Animated.timing(rotateAnim, {
toValue: 1, toValue: 1,
duration: 30000, duration: ANIMATION_DURATION.rotate,
useNativeDriver: true, useNativeDriver: true,
}) })
).start(); );
}, []); rotateAnimation.start();
// Cleanup animations on unmount to prevent memory leaks
return () => {
pulseAnimation.stop();
glowAnimation.stop();
rotateAnimation.stop();
};
}, [pulseAnim, glowAnim, rotateAnim]);
const openVaultWithMnemonic = () => { const openVaultWithMnemonic = () => {
const words = generateMnemonic(); const words = generateMnemonic();
@@ -230,23 +252,23 @@ export default function SentinelScreen() {
Animated.sequence([ Animated.sequence([
Animated.timing(pulseAnim, { Animated.timing(pulseAnim, {
toValue: 1.15, toValue: 1.15,
duration: 150, duration: ANIMATION_DURATION.heartbeatPress,
useNativeDriver: true, useNativeDriver: true,
}), }),
Animated.timing(pulseAnim, { Animated.timing(pulseAnim, {
toValue: 1, toValue: 1,
duration: 150, duration: ANIMATION_DURATION.heartbeatPress,
useNativeDriver: true, useNativeDriver: true,
}), }),
]).start(); ]).start();
// Add new log // Add new log using functional update to avoid stale closure
const newLog: KillSwitchLog = { const newLog: KillSwitchLog = {
id: Date.now().toString(), id: Date.now().toString(),
action: 'HEARTBEAT_CONFIRMED', action: 'HEARTBEAT_CONFIRMED',
timestamp: new Date(), timestamp: new Date(),
}; };
setLogs([newLog, ...logs]); setLogs((prevLogs) => [newLog, ...prevLogs]);
// Reset status if warning // Reset status if warning
if (status === 'warning') { if (status === 'warning') {
@@ -324,7 +346,7 @@ export default function SentinelScreen() {
colors={currentStatus.gradientColors} colors={currentStatus.gradientColors}
style={styles.statusCircle} style={styles.statusCircle}
> >
<Ionicons name={currentStatus.icon as any} size={56} color="#fff" /> <Ionicons name={currentStatus.icon} size={56} color="#fff" />
</LinearGradient> </LinearGradient>
</Animated.View> </Animated.View>
<Text style={[styles.statusLabel, { color: currentStatus.color }]}> <Text style={[styles.statusLabel, { color: currentStatus.color }]}>
@@ -390,6 +412,8 @@ export default function SentinelScreen() {
style={styles.vaultAccessButton} style={styles.vaultAccessButton}
onPress={openVaultWithMnemonic} onPress={openVaultWithMnemonic}
activeOpacity={0.8} activeOpacity={0.8}
accessibilityLabel="Open Shadow Vault"
accessibilityRole="button"
> >
<Text style={styles.vaultAccessButtonText}>Open</Text> <Text style={styles.vaultAccessButtonText}>Open</Text>
</TouchableOpacity> </TouchableOpacity>
@@ -400,6 +424,8 @@ export default function SentinelScreen() {
style={styles.heartbeatButton} style={styles.heartbeatButton}
onPress={handleHeartbeat} onPress={handleHeartbeat}
activeOpacity={0.9} activeOpacity={0.9}
accessibilityLabel="Signal the watch - Confirm your presence"
accessibilityRole="button"
> >
<LinearGradient <LinearGradient
colors={[colors.nautical.teal, colors.nautical.seafoam]} colors={[colors.nautical.teal, colors.nautical.seafoam]}
@@ -451,6 +477,8 @@ export default function SentinelScreen() {
style={styles.vaultCloseButton} style={styles.vaultCloseButton}
onPress={() => setShowVault(false)} onPress={() => setShowVault(false)}
activeOpacity={0.85} activeOpacity={0.85}
accessibilityLabel="Close vault"
accessibilityRole="button"
> >
<Ionicons name="close" size={20} color={colors.nautical.cream} /> <Ionicons name="close" size={20} color={colors.nautical.cream} />
</TouchableOpacity> </TouchableOpacity>
@@ -468,15 +496,17 @@ export default function SentinelScreen() {
style={styles.mnemonicOverlay} style={styles.mnemonicOverlay}
behavior={Platform.OS === 'ios' ? 'padding' : undefined} behavior={Platform.OS === 'ios' ? 'padding' : undefined}
> >
<LinearGradient <View ref={mnemonicRef} collapsable={false}>
colors={[colors.sentinel.cardBackground, colors.sentinel.backgroundGradientEnd]} <LinearGradient
style={styles.mnemonicCard} colors={[colors.sentinel.cardBackground, colors.sentinel.backgroundGradientEnd]}
ref={mnemonicRef} style={styles.mnemonicCard}
> >
<TouchableOpacity <TouchableOpacity
style={styles.mnemonicClose} style={styles.mnemonicClose}
onPress={() => setShowMnemonic(false)} onPress={() => setShowMnemonic(false)}
activeOpacity={0.85} activeOpacity={0.85}
accessibilityLabel="Close mnemonic modal"
accessibilityRole="button"
> >
<Ionicons name="close" size={18} color={colors.sentinel.textSecondary} /> <Ionicons name="close" size={18} color={colors.sentinel.textSecondary} />
</TouchableOpacity> </TouchableOpacity>
@@ -514,6 +544,9 @@ export default function SentinelScreen() {
onPress={handleScreenshot} onPress={handleScreenshot}
activeOpacity={0.85} activeOpacity={0.85}
disabled={isCapturing} disabled={isCapturing}
accessibilityLabel="Take screenshot backup of mnemonic"
accessibilityRole="button"
accessibilityState={{ disabled: isCapturing }}
> >
<Text style={styles.mnemonicPrimaryText}> <Text style={styles.mnemonicPrimaryText}>
{isCapturing ? 'CAPTURING...' : 'PHYSICAL BACKUP (SCREENSHOT)'} {isCapturing ? 'CAPTURING...' : 'PHYSICAL BACKUP (SCREENSHOT)'}
@@ -523,6 +556,8 @@ export default function SentinelScreen() {
style={styles.mnemonicSecondaryButton} style={styles.mnemonicSecondaryButton}
onPress={handleEmailBackup} onPress={handleEmailBackup}
activeOpacity={0.85} activeOpacity={0.85}
accessibilityLabel="Send mnemonic backup via email"
accessibilityRole="button"
> >
<Text style={styles.mnemonicSecondaryText}>EMAIL BACKUP</Text> <Text style={styles.mnemonicSecondaryText}>EMAIL BACKUP</Text>
</TouchableOpacity> </TouchableOpacity>
@@ -542,12 +577,15 @@ export default function SentinelScreen() {
style={styles.emailSendButton} style={styles.emailSendButton}
onPress={handleSendEmail} onPress={handleSendEmail}
activeOpacity={0.85} activeOpacity={0.85}
accessibilityLabel="Send backup email"
accessibilityRole="button"
> >
<Text style={styles.emailSendText}>SEND EMAIL</Text> <Text style={styles.emailSendText}>SEND EMAIL</Text>
</TouchableOpacity> </TouchableOpacity>
</View> </View>
) : null} ) : null}
</LinearGradient> </LinearGradient>
</View>
</KeyboardAvoidingView> </KeyboardAvoidingView>
</Modal> </Modal>
</View> </View>