Skip to content

Latest commit

 

History

History
271 lines (239 loc) · 13.8 KB

File metadata and controls

271 lines (239 loc) · 13.8 KB

Click Tracker - Application Architecture

Overview

Click Tracker is an Electron-based desktop application that monitors and tracks user productivity by recording mouse clicks, keyboard activity, and time duration across multiple projects and tasks.


Architecture Diagram

┌─────────────────────────────────────────────────────────────────┐
│                     ELECTRON MAIN PROCESS                       │
│                      (src/main.js)                              │
│                                                                 │
│  • Window Management                                           │
│  • uIOhook Event Handlers (clicks & keystrokes)               │
│  • IPC Request Handlers                                        │
│  • Timer Service Management                                    │
└──────────────────────────┬──────────────────────────────────────┘
                           │
                  IPC Bridge (preload.js)
                           │
┌──────────────────────────┴──────────────────────────────────────┐
│              RENDERER PROCESS (React)                           │
│                                                                 │
│  ┌────────────────────────────────────────────────────────┐   │
│  │  App.js (Root Component)                               │   │
│  │  • Routes projects to selected project                 │   │
│  │  • Passes handlers to children                         │   │
│  └────────────────┬─────────────────────────────┬─────────┘   │
│                   │                             │             │
│  ┌────────────────▼──────┐      ┌──────────────▼──────────┐  │
│  │  ProjectList.js       │      │  TaskTracker.js        │  │
│  │  • List all projects  │      │  • Task table display  │  │
│  │  • Add project        │      │  • Start/Stop tracking │  │
│  │  • Delete project     │      │  • Real-time stats     │  │
│  │  • Select project     │      │  • Add/Delete tasks    │  │
│  └───────────────────────┘      └────────────────────────┘  │
│                                                                 │
│  Styles:                                                        │
│  • App.css (main layout, header, sidebar, content area)       │
│  • ProjectList.css (project items, modals)                    │
│  • TaskTracker.css (task table, buttons, forms)               │
│  • index.css (global styles, scrollbars, fonts)               │
└───────────────────────┬──────────────────────────────────────┘
                        │
                 IPC API Calls
                        │
┌───────────────────────┴──────────────────────────────────────┐
│              SERVICES (Node.js Backend)                      │
│                                                              │
│  ┌──────────────────────────────────────────────────────┐   │
│  │  database.js - SQLite Operations                     │   │
│  │  • CRUD projects and tasks                           │   │
│  │  • Record activity events                            │   │
│  │  • Calculate statistics (clicks, keys, duration)    │   │
│  │  • Cascading deletes with foreign keys              │   │
│  └──────────────────────────────────────────────────────┘   │
│                                                              │
│  ┌──────────────────────────────────────────────────────┐   │
│  │  timerService.js - Timing Management                │   │
│  │  • Start/Stop/Pause timer                            │   │
│  │  • Emit tick events every second                     │   │
│  │  • Calculate elapsed time                            │   │
│  └──────────────────────────────────────────────────────┘   │
│                                                              │
│  ┌──────────────────────────────────────────────────────┐   │
│  │  mouseTracker.js - Mouse Event Listener             │   │
│  │  • Attached to uIOhook click events                 │   │
│  │  • Tracks click coordinates and count               │   │
│  └──────────────────────────────────────────────────────┘   │
│                                                              │
│  ┌──────────────────────────────────────────────────────┐   │
│  │  keyboardTracker.js - Keyboard Event Listener       │   │
│  │  • Attached to uIOhook keydown events               │   │
│  │  • Tracks keystroke count                            │   │
│  └──────────────────────────────────────────────────────┘   │
│                                                              │
│  ┌──────────────────────────────────────────────────────┐   │
│  │  activityDetector.js - Idle Detection               │   │
│  │  • Monitors activity status                          │   │
│  │  • Calculates idle time                              │   │
│  └──────────────────────────────────────────────────────┘   │
└───────────────────────┬──────────────────────────────────────┘
                        │
                   uIOhook-napi
                        │
┌───────────────────────┴──────────────────────────────────────┐
│           NATIVE SYSTEM HOOKS (uIOhook)                      │
│                                                              │
│  • System-wide click detection (mouse events)               │
│  • System-wide keyboard detection (key events)              │
│  • Works globally even when app is not focused              │
└───────────────────────┬──────────────────────────────────────┘
                        │
┌───────────────────────┴──────────────────────────────────────┐
│              DATABASE (SQLite)                               │
│  Location: %APPDATA%/click-tracker/tracker.db               │
│                                                              │
│  Tables:                                                     │
│  • projects (id, name, description, status, created_at)    │
│  • tasks (id, project_id, name, duration, timestamps)       │
│  • activity_events (id, task_id, event_type, coords, key)  │
└──────────────────────────────────────────────────────────────┘

Data Flow

Starting Task Tracking

User clicks START → TaskTracker.handleStartTask() 
  → window.api.startTracking(taskId)
  → main.js 'start-tracking' handler
  → Start uIOhook listeners for THIS task
  → Start timerService
  → Send 'timer-tick' events to renderer

Recording Activity

User clicks mouse/presses key
  → uIOhook detects event (global hook)
  → main.js handler fires
  → database.recordEvent(taskId, eventType, ...)
  → mainWindow.webContents.send('click-event'|'key-event')
  → React state updates live counter
  → Database accumulates event count

Stopping Task

User clicks STOP → TaskTracker.handleStopTask()
  → window.api.stopTask(activeTaskId)
  → main.js 'stop-task' handler
  → Stop timerService
  → database.stopTask(taskId, durationSeconds)
  → Remove all uIOhook listeners
  → Clear active task state

Displaying Stats

User starts task OR navigates to project
  → TaskTracker.loadTasks()
  → For each task: window.api.getTaskStats(taskId)
  → database.getTaskStats(taskId)
  → Query: COUNT events by type WHERE task_id = ?
  → Return: { clicks: X, keystrokes: Y }
  → React displays stats in table

IPC API Methods

Invocations (Request-Response):

  • getProjects() - Fetch all projects
  • createProject(name, description) - Create new project
  • deleteProject(projectId) - Delete project with cascading deletes
  • addTask(projectId, taskName) - Add task without tracking
  • startTracking(taskId) - Start tracking existing task
  • stopTask(taskId) - Stop current tracking
  • deleteTask(taskId) - Delete task and events
  • getProjectTasks(projectId) - Get tasks for project
  • getTaskStats(taskId) - Get click/keystroke counts
  • getTaskEvents(taskId) - Get all events for task

Events (Async Notifications):

  • timer-tick - Timer update (00:00:00 format)
  • click-event - Mouse click detected
  • key-event - Key press detected

Key Technologies

Component Technology Purpose
Desktop Framework Electron 40.3.0 Cross-platform desktop app
UI Framework React 19.2.4 Component-based UI with hooks
Bundler Webpack 5.105.1 Module bundling & dev server
Database SQLite3 5.1.7 Local data persistence
System Hooks uiohook-napi 1.5.4 Global keyboard/mouse detection
Styling CSS3 Gradient, animations, dark theme

Folder Structure

src/
├── App.js                 # Root React component
├── index.js              # Entry point
├── main.js               # Electron main process
├── preload.js            # IPC bridge (secure context)
├── components/
│   ├── ProjectList.js    # Project sidebar
│   └── TaskTracker.js    # Task tracking UI
├── services/
│   ├── database.js       # SQLite operations
│   ├── timerService.js   # Timing logic
│   ├── mouseTracker.js   # Click listener
│   ├── keyboardTracker.js # Key listener
│   └── activityDetector.js # Idle detection
└── styles/
    ├── index.css         # Global styles
    ├── App.css           # App layout
    ├── ProjectList.css   # Projects styling
    └── TaskTracker.css   # Tasks styling

State Management

Renderer State (React):

  • tasks - Array of task objects
  • taskStats - Statistics map by task ID
  • activeTaskId - Currently tracking task
  • timer - Formatted time string (HH:MM:SS)
  • liveStats - Current click/key counters
  • selectedProject - Active project object

Main Process State:

  • currentTaskId - Active task in tracking
  • clickHandler - Current click event listener
  • keyHandler - Current keyboard event listener

Database State:

  • Persistent SQLite database with 3 tables
  • Cascading foreign key relationships
  • Accumulated duration across sessions

Event Listener Lifecycle (Per Task)

START TASK
  ↓
Clear old listeners (removeListener for click/keydown)
  ↓
Define NEW click & keydown handlers for CURRENT task
  ↓
Register handlers: uIOhook.on('click', handler)
                   uIOhook.on('keydown', handler)
  ↓
uIOhook.start()
  ↓
Track events [User actively working]
  ↓
STOP TASK
  ↓
removeListener for both handlers
  ↓
uIOhook.stop()
  ↓
Database updated with accumulated stats

Security Model

  • Context Isolation - Renderer cannot access Node.js directly
  • Preload Bridge - Controlled IPC API exposure
  • No nodeIntegration - Renderer process sandboxed
  • Validation - All IPC messages validated on main process