Merge dev into master: goals, weekly reports, notifications, performance, and docs overhaul#3
Merged
arshsisodiya merged 70 commits intomasterfrom Mar 16, 2026
Merged
Merge dev into master: goals, weekly reports, notifications, performance, and docs overhaul#3arshsisodiya merged 70 commits intomasterfrom
arshsisodiya merged 70 commits intomasterfrom
Conversation
Previously totalScreenTime only summed productive + neutral + other + unproductive, excluding entertainment, communication, and system categories. Now uses sum(category_data.values()) to count ALL non-ignored app usage as screen time. Productivity formula unchanged entertainment/communication/system contribute 0 weight, lowering productivity% when present (correct behavior).
… leak The _last_logged dict grew unboundedly with every unique file path seen. Now uses OrderedDict with FIFO eviction when exceeding _MAX_THROTTLE_CACHE.
… connections get() now checks a thread-safe dict cache before hitting SQLite. set() and delete() write-through to both DB and cache.
top_app is now computed during the existing category_rows iteration, removing a separate GROUP BY + ORDER BY query on daily_stats.
Historical dates cached permanently (immutable). Today's score refreshes every 45s instead of recalculating on every request.
Protects reads in _process_guard and writes in _limit_monitor with _blocked_apps_lock for proper thread safety.
…cache File changes are now detected via os.path.getmtime and the cache refreshes automatically. Also switched is_ignored to O(1) set lookup.
Frontend now makes a single request for settings, ignored apps, available dates, heatmap, spark series, and update status on mount.
Added warm() method to SettingsCache and call it from main() right after init_db(). First get() now reads from pre-populated cache.
- Track fractional hour position (nowFrac) via 15s interval - Render 1px gradient vertical line at (nowFrac/24)*100% across bar area - Pulsing 7px dot at needle top using new now-pulse keyframe - Needle only renders when selectedDate === today (hidden on historical views) - Added now-pulse keyframe to DONUT_CSS
- Segmented 6px bar below Active/Idle stat boxes showing proportional split - Green gradient segment for active time, muted slate for idle - Percentage labels underneath: X% active / X% idle - Animates in with 1.4s spring transition on date change - Guarded with totalScreenTime > 0 check to avoid rendering on empty days
- Added prevFilter state and handleFilterChange handler
- Count badge gets key={cat-cnt} so React remounts it on filter change
- Newly active chip count plays badge-pop spring animation (scale 0.6 → 1.35 → 1)
- badge-pop keyframe injected via scoped style tag in component return
…egory totals - Tooltip: clamp tipX against containerRef.current.offsetWidth so tooltips near left/right edges never overflow the card - Gap markers: replace invisible dashed lines with visible 💤 Xh break pill labels on the ruler, with dashed vertical lines running through all category rows - Category totals: label column now shows total time per category below the category name (e.g. 💼 productive / 3h 20m) using fmtTime
-Remind Later now opens an inline SnoozePicker instead of just closing - Four snooze options: 1 hour, 4 hours, Tomorrow, 1 week - Selected snooze writes stasis_remind_after timestamp to localStorage - Confirmation state shown after snooze selection, auto-closes after 1.4s - Back button cancels picker and returns to normal footer - Note: check localStorage stasis_remind_after in update check logic to suppress dialog during snooze window
- React.memo on ScreenTimeCard, ProductivityCard, FocusCard, InputActivityCard - React.memo on AppRow and BrowserRow in AppsPage - Memoize DateNavigator and NoiseOverlay with React.memo - Replace backdrop-filter: blur(20px) with solid rgba backgrounds (GPU savings) - Reduce NoiseOverlay feTurbulence numOctaves from 4 to 2 - Replace all transition: 'all' with specific property transitions - Reduce double drop-shadow to single in CategoryBreakdown donut - Cache BrowserRow site-stats fetch results by date+app key - Fix sparkline footer negative margins (remove width calc + marginLeft) - Shared RAF loop for useCountUp (batches 4+ animations into 1 rAF) - Replace transition: all in UpdateDialog, TrendChip, filter chips, nav buttons
Goals & Targets: - New goals/goal_logs/limit_events DB tables with full CRUD - Goals API (create, update, delete, progress, history) - GoalsPage.jsx with progress rings, presets, edit/delete modals - Supports daily_screen_time, productive_time, productivity_pct, focus_score Weekly Report: - Report generation with daily breakdown, top apps, category stats - Limit discipline tracking (hits & edits per app) - Goal achievement summaries with success rates - Humanized insights with conversational language - WeeklyReportPage.jsx with animated bars, week navigation, insights - Telegram delivery endpoint with send button Integration: - Limit event logging in blocking_service and limits_routes - weekly_report_telegram toggle in settings (backend + frontend) - Goals and Reports tabs wired into WellbeingDashboard
…scheduler - Improve category donut layout and hover highlighting - Keep stat mini-sparklines and remove daily bar overlay line - Replace copy action with direct PDF export download - Add jsPDF dependency for export - Return full Mon-Sun daily breakdown including empty days - Add weekly trend series for report metrics - Add weekly Telegram auto-send scheduler worker - Track last auto-sent week in settings defaults
- add compact themed compare-week picker with available tracked weeks - add multi-format export options: PDF, CSV, JSON, Telegram - add weekly report verbosity setting in Settings - add app trend arrows, smart category insights, goal drift alerts - add goal impact correlation and what-changed summary blocks - add compare endpoint and available-weeks endpoint for reports
…and limits Implement a complete Windows desktop notification pipeline for goal and app-limit events, including backend delivery, runtime triggers, developer diagnostics, and production-safe action routing. Backend and runtime: - Add DesktopNotifier in src/core/desktop_notifications.py using winotify as the single reliable backend. - Add event typing, cooldown dedupe, per-event enable/disable gating, quiet-hours filtering, and limit snooze support. - Add notification history tracking (bounded deque) for diagnostics. - Add notification action URL builder for stasis:// deep links. - Trigger rich app-limit notifications in BlockingService with over-limit details and actions. - Add goal-threshold/goal-achieved notifications with first-check and transition detection. - Start BlockingService unconditionally on startup so goal checks run even without app limits. - Add settings defaults for notifications, event toggles, quiet hours, and snooze timestamp. - Add API support for notification settings read/write plus endpoints for test, test-goal, test-limit, history, and action handling. Windows identity and attribution hardening: - Add startup self-heal for notification identity via Start Menu shortcut + AppUserModelID. - Use branded identity (Stasis: Digital Wellbeing) and set shortcut icon for proper Notification Center attribution. Frontend + Tauri production flow: - Add Developer notification controls in Settings (event toggles, quiet hours, tests, history). - Move test utilities into Developer section and keep Developer at the end of Settings navigation. - Add deep-link bridge from Tauri (stasis-deep-link event) to frontend custom event. - Parse deep-link actions in dashboard to open Goals/Limits and call snooze action API. - Register and clean up stasis:// protocol in NSIS installer hooks so action buttons work in packaged builds. Dependency updates: - Add winotify to requirements.txt for toast delivery.
…silent limit actions Improve notification utility and UX by shipping: - End-of-day digest notifications at user-selected time with screen-time vs goal, top distraction, productive ratio, and best streak. - Enhanced app-limit action set: Snooze 15m, Snooze 1h, Extend 10m, Keep blocked. - Context-aware quiet mode for non-critical events (fullscreen/presentation/game/focus context), while critical limit alerts still pass through. - New notification settings keys and API wiring for digest and context quiet controls. - Silent backend handling for backend-only deep-link actions in Tauri, preventing app window focus/open when choosing limit decision actions. - Frontend routing updates for new notification actions and review-day deep link.
Render only the active settings section so hidden tabs do not inflate container height. This removes empty scroll area in General, Telegram, and other settings tabs.
Keep settings sections mounted and animate panel transitions while tracking active panel height. This preserves smooth tab switching and avoids blank tail scroll.
Add weekly hourly activity endpoint and wire weekly report heatmap data flow. Includes week-based aggregation for hourly grid with productivity metrics and dominant category support.
There was a problem hiding this comment.
Pull request overview
This is a large dev-to-master merge that introduces Goals & Targets integration, Weekly Reports, Windows Notification Center support, performance optimizations (batched writes, caching, threaded API, background URL resolution), architectural refactoring (settings schema, blocking service state management), UI improvements, and a comprehensive documentation refresh including a privacy policy.
Changes:
- Added goals/limits/notification subsystem with DB tables, API routes, desktop notifications via winotify, deep-link protocol handling, and frontend goal status UI in overview cards
- Performance improvements including batched file monitor writes, settings caching, focus score caching, background URL resolver, consolidated bundle endpoints, shared RAF loop for animations, and visibility-aware polling
- Documentation overhaul with MkDocs privacy policy page, expanded API reference, architecture docs, and CI/CD workflows for dev/master branches
Reviewed changes
Copilot reviewed 62 out of 65 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/services/blocking_service.py | Thread-safe blocked apps management, goal/digest notification checks, lock-based state updates |
| src/core/desktop_notifications.py | New Windows notification system with winotify, cooldown/dedup, quiet hours, context-aware suppression |
| src/core/file_monitor.py | Batched DB writes via queue + flush thread, bounded throttle cache |
| src/core/url_sniffer.py | Background URL resolver thread to avoid blocking logger loop |
| src/core/activity_logger.py | Uses cached URL resolver, standardized boolean settings |
| src/core/startup.py | Notification identity self-heal (Start Menu shortcut + AUMID) |
| src/core/settings_cache.py | Added warm() method for pre-loading |
| src/config/settings_manager.py | Thread-safe in-memory cache for settings, notification defaults |
| src/config/ignored_apps_manager.py | Mtime-based cache invalidation, O(1) set lookup |
| src/database/database.py | Goals/limit_events tables, blocked-state migration, new CRUD functions |
| src/utils/logger.py | Guard against duplicate handler setup |
| src/main.py | Weekly report scheduler thread, notification identity setup, settings cache warm |
| src/api/settings_routes.py | Notification test endpoints, action handler for deep-link actions |
| src/api/goals_routes.py | Full CRUD + progress/history API for goals |
| src/api/limits_routes.py | Reblock endpoint, limit event logging |
| src/api/system_routes.py | Init-bundle endpoint for consolidated startup fetch |
| src/api/dashboard_routes.py | Dashboard-bundle endpoint, top-app optimization |
| src/api/activity_routes.py | Weekly hourly activity grid, date-bounded queries |
| src/api/spark_routes.py | Date-bounded spark query |
| src/api/focus_routes.py | Focus score caching, index-friendly date filtering |
| src/api/danger_routes.py | Standardized boolean settings ("true"/"false") |
| src/api/api_server.py | Threaded Werkzeug server |
| frontend/src/shared/hooks.js | Shared RAF loop, useVisibilityPolling hook |
| frontend/src/shared/components.jsx | GoalStatusBlock, SectionCard spread props, removed backdropFilter |
| frontend/src/shared/UpdateDialog.jsx | Snooze picker for update reminders |
| frontend/src/pages/*.jsx | Goal integration in overview cards, memo wrapping, responsive grids, live now-needle |
| frontend/src/pages/SettingsPage.jsx | Developer section with notification controls/test/history |
| frontend/src/pages/AppsPage.jsx | Virtualized rendering, site stats cache |
| frontend/src/index.css | CSS custom properties, hover utilities, prefers-reduced-motion |
| frontend/src/main.jsx | Tauri deep-link event listener |
| frontend/src-tauri/src/main.rs | Deep-link protocol handling, backend-only action dispatch |
| frontend/src-tauri/nsis/installer.nsh | Deep-link protocol registration, privacy consent page |
| frontend/src-tauri/nsis/privacy.txt | Expanded privacy policy text |
| frontend/package.json | Added jspdf dependency |
| docs/*.md, mkdocs.yml | Privacy policy, expanded API reference, architecture, config docs |
| README.md | Goals, weekly reports, notifications documentation |
| .github/workflows/*.yml | CI for dev/master, auto-PR, auto-merge workflows |
| requirements.txt | Added winotify |
| .gitignore | Added site/ |
Files not reviewed (1)
- frontend/package-lock.json: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
Comment on lines
+220
to
+222
| return f"<p>Extended {app_name} by {max(1, minutes)} minute(s).</p>", 200, {"Content-Type": "text/html; charset=utf-8"} | ||
| except Exception as exc: | ||
| return f"<p>Failed to extend limit: {exc}</p>", 500, {"Content-Type": "text/html; charset=utf-8"} |
Clean up unused vars/imports, ignore generated Tauri artifacts in ESLint, and align lint rules with the current frontend codebase. Leaves a small set of non-blocking hook dependency warnings for follow-up.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR promotes all current
devchanges intomasterand preserves commit history as-is (no squash/rebase).Highlights
This release delivers a major dashboard evolution with deeper Goals integration, expanded Weekly Reports, Notification Center support, performance optimizations, architectural cleanup, and a full documentation refresh.
What’s included
New Features
Performance & Optimization
Architecture & Refactoring
UI & Visual Improvements
Bug Fixes
Documentation & Assets
Under the Hood
CI/CD & Installer updates included
Validation notes
devwith all intended commits