Skip to content

Latest commit

 

History

History
241 lines (204 loc) · 8.38 KB

File metadata and controls

241 lines (204 loc) · 8.38 KB

Tindy Popup - Architecture Overview

📁 New Modular Structure

popup/
├── index.js                    # 🎯 Main orchestrator (120 lines)
│
├── utils/                      # 🔧 Utility functions
│   ├── dom.js                  # DOM caching & manipulation (105 lines)
│   ├── chrome-api.js           # Chrome API wrappers (85 lines)
│   └── helpers.js              # General utilities (40 lines)
│
├── services/                   # 💼 Business logic
│   ├── tinder-detector.js      # Tinder detection (40 lines)
│   ├── stats-service.js        # Stats polling (85 lines)
│   └── settings-service.js     # Settings management (60 lines)
│
├── components/                 # 🎨 UI components
│   ├── status-badge.js         # Status indicator (35 lines)
│   ├── stats-display.js        # Stats display (30 lines)
│   ├── controls.js             # Buttons & sliders (95 lines)
│   ├── mode-selector.js        # Mode selection (50 lines)
│   └── navigation.js           # Navigation buttons (35 lines)
│
└── state/                      # 📊 State management
    └── app-state.js            # Centralized state (125 lines)

Total: ~905 lines across 13 focused files Old: 417 lines in 1 monolithic file

🔄 Data Flow Architecture

┌─────────────────────────────────────────────────────────────┐
│                        index.js                              │
│                   (Main Orchestrator)                        │
│  • Initializes all services, state, and components          │
│  • Sets up callbacks and event listeners                    │
│  • Coordinates application lifecycle                        │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                     app-state.js                             │
│                  (State Management)                          │
│  • Centralized state (isActive, stats, settings)            │
│  • Provides callbacks for state changes                     │
│  • Batches UI updates for performance                       │
└─────────────────────────────────────────────────────────────┘
                              │
                ┌─────────────┼─────────────┐
                ▼             ▼             ▼
    ┌──────────────┐  ┌──────────────┐  ┌──────────────┐
    │   Services   │  │  Components  │  │    Utils     │
    └──────────────┘  └──────────────┘  └──────────────┘

🎯 Component Interaction Flow

User Action (Click/Input)
        │
        ▼
┌─────────────────┐
│   Component     │ ◄─── Event Listener
│  (controls.js)  │
└─────────────────┘
        │
        ▼
┌─────────────────┐
│    Service      │ ◄─── Business Logic
│ (settings.js)   │
└─────────────────┘
        │
        ▼
┌─────────────────┐
│  Chrome API     │ ◄─── Send Message to Content Script
│ (chrome-api.js) │
└─────────────────┘
        │
        ▼
┌─────────────────┐
│   App State     │ ◄─── Update State
│ (app-state.js)  │
└─────────────────┘
        │
        ▼
┌─────────────────┐
│   Components    │ ◄─── UI Update via Callbacks
│  (all UI files) │
└─────────────────┘

📦 Module Responsibilities

Utils Layer (Foundation)

  • dom.js: DOM element caching, manipulation helpers
  • chrome-api.js: Chrome extension API wrappers
  • helpers.js: Debounce, throttle, formatting utilities

Services Layer (Business Logic)

  • tinder-detector.js: Detects if user is on Tinder
  • stats-service.js: Loads and polls statistics
  • settings-service.js: Manages settings updates

Components Layer (UI Logic)

  • status-badge.js: Active/inactive status display
  • stats-display.js: Statistics visualization
  • controls.js: Toggle, speed slider, stealth checkbox
  • mode-selector.js: Swipe mode selection
  • navigation.js: Navigation buttons

State Layer (Coordination)

  • app-state.js: Centralized state management with callbacks

Orchestration Layer (Entry Point)

  • index.js: Initializes and coordinates everything

✅ Benefits of This Architecture

1. Single Responsibility Principle

Each file has ONE clear purpose. Easy to understand what each module does.

2. Maintainability

  • Bug in stats display? → Check stats-display.js
  • Issue with settings? → Check settings-service.js
  • DOM performance problem? → Check dom.js

3. Testability

Each module can be unit tested independently:

// Test stats-display.js
import { StatsDisplay } from './components/stats-display.js';
// Test in isolation

4. Reusability

Utils and services can be reused across different parts:

// Use debounce in multiple components
import { debounce } from './utils/helpers.js';

5. Scalability

Adding new features is straightforward:

  • New UI element? → Add component
  • New business logic? → Add service
  • New utility? → Add to utils

6. Performance

  • DOM elements cached once
  • Updates batched using requestAnimationFrame
  • Only changed values updated
  • Smart polling with RAF

🆚 Before vs After

Before (Monolithic)

popup.js (417 lines)
├── DOM caching
├── Event listeners
├── Chrome API calls
├── Stats polling
├── Settings management
├── UI updates
├── State management
└── Everything mixed together ❌

After (Modular)

popup/ (13 files, ~905 lines)
├── Clear separation of concerns ✅
├── Easy to find and fix bugs ✅
├── Testable modules ✅
├── Reusable components ✅
└── Scalable architecture ✅

🚀 How to Add a New Feature

Example: Add a "Pause Timer" feature

  1. Add utility (if needed)

    // utils/helpers.js
    export function formatTime(seconds) { ... }
  2. Create service

    // services/timer-service.js
    export class TimerService { ... }
  3. Create component

    // components/timer-display.js
    export class TimerDisplay { ... }
  4. Update state

    // state/app-state.js
    this.pauseTime = null;
  5. Wire up in index.js

    this.timerService = new TimerService();
    this.timerDisplay = new TimerDisplay();

📝 Code Quality Improvements

  • ES6 Modules: Proper import/export
  • JSDoc Comments: Every function documented
  • Consistent Naming: Clear, descriptive names
  • Error Handling: Proper try-catch blocks
  • Performance: Optimized DOM operations
  • Separation: Clear boundaries between layers

🎓 Learning from This Refactor

This refactor demonstrates:

  1. How to break down monolithic code
  2. Proper separation of concerns
  3. Service-oriented architecture
  4. Component-based UI design
  5. Centralized state management
  6. Performance optimization techniques

Old Code: 417 lines, everything mixed together New Code: 13 focused modules, clear architecture Result: Maintainable, scalable, professional codebase ✨