/** * Duplicate Detection System for React Native * Matches Swift version's duplicate detection logic */ export interface ToneDetection { lastDetectedTone: string; lastDetectionTime: number; } export class DuplicateDetector { private detectedTones: ToneDetection[] = []; private duplicateDetectionTiming: number = 20000; // 20 seconds in milliseconds constructor(duplicateDetectionTiming?: number) { if (duplicateDetectionTiming !== undefined) { this.duplicateDetectionTiming = duplicateDetectionTiming; } } /** * Check if a sequence is a duplicate and add it if it's new * @param sequence The detected tone sequence * @returns true if the sequence is new (not a duplicate), false if it's a duplicate */ public checkAndAddSequence(sequence: string): boolean { const now = Date.now(); const window = this.duplicateDetectionTiming / 1000.0; // Convert to seconds console.log(`🎯 DuplicateDetector: Duplicate detection window: ${window}s`); // Evict stale detections const beforeCount = this.detectedTones.length; this.detectedTones = this.detectedTones.filter( detection => (now - detection.lastDetectionTime) <= this.duplicateDetectionTiming ); const afterCount = this.detectedTones.length; console.log(`🎯 DuplicateDetector: Evicted ${beforeCount - afterCount} stale detections, ${afterCount} remaining`); // Check if this sequence was already detected recently const existingDetection = this.detectedTones.find( detection => detection.lastDetectedTone === sequence ); if (existingDetection) { // Already detected recently; ignore console.log(`🎯 DuplicateDetector: ❌ DUPLICATE DETECTED - sequence '${sequence}' already detected at ${new Date(existingDetection.lastDetectionTime).toISOString()}`); return false; } // New sequence — record it console.log(`🎯 DuplicateDetector: ✅ NEW SEQUENCE DETECTED - '${sequence}' at ${new Date(now).toISOString()}`); this.detectedTones.push({ lastDetectedTone: sequence, lastDetectionTime: now }); return true; } /** * Update the duplicate detection timing window * @param timingMs Timing window in milliseconds */ public updateDuplicateDetectionTiming(timingMs: number): void { this.duplicateDetectionTiming = timingMs; console.log(`🎯 DuplicateDetector: Updated duplicate detection timing to ${timingMs}ms`); } /** * Get the current duplicate detection timing * @returns Timing window in milliseconds */ public getDuplicateDetectionTiming(): number { return this.duplicateDetectionTiming; } /** * Clear all detected sequences */ public clear(): void { this.detectedTones = []; console.log('🎯 DuplicateDetector: Cleared all detected sequences'); } /** * Get the number of currently tracked sequences * @returns Number of sequences being tracked */ public getTrackedSequenceCount(): number { return this.detectedTones.length; } }