Skip to content

Commit f49cb72

Browse files
committed
feat: add new widgets for browser activity, focus coaching, goal progress, quick capture, and session pulse
- Implemented BrowserActivityWidget to display current browser domain stats and connection status. - Created FocusCoachWidget for managing focus sessions with start/stop functionality and session tracking. - Developed GoalProgressWidget to show usage goals and progress towards them. - Added QuickCaptureWidget for quick note and todo capture with local storage support. - Introduced SessionPulseWidget to visualize focus time and interruptions throughout the day. - Added useWidgetErrorReporter hook for error handling across widgets.
1 parent a486788 commit f49cb72

98 files changed

Lines changed: 7973 additions & 1461 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

AGENTS.md

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
# TimeLens Agent Guide
2+
3+
This document helps AI agents contribute to TimeLens safely and consistently.
4+
5+
## Project Overview
6+
7+
TimeLens is a local-first screen-time tracker and desktop widget platform built with:
8+
9+
- **Frontend**: React + TypeScript + Vite + Tailwind CSS
10+
- **Desktop host**: Tauri v2 + Rust
11+
- **Database**: SQLite (local only, no cloud)
12+
- **Extensions**: Browser extension (Edge/Chrome), VS Code extension
13+
14+
The project root contains the web frontend. The Tauri backend lives in `src-tauri/`.
15+
16+
## Quick Commands
17+
18+
Always run these after non-trivial changes:
19+
20+
```bash
21+
npm run typecheck # TypeScript check
22+
npm run lint # ESLint (expect 9 pre-existing warnings)
23+
npm run test # Frontend unit tests
24+
```
25+
26+
For Rust/backend changes (run from `src-tauri/`):
27+
28+
```bash
29+
cargo test
30+
cargo check
31+
```
32+
33+
For a full release build:
34+
35+
```bash
36+
npm run tauri:build
37+
```
38+
39+
## Architecture
40+
41+
### Frontend (`src/`)
42+
43+
- `src/pages/` — Full-page views (Dashboard, Settings, Focus Mode, Widget Center, etc.)
44+
- `src/widgets/` — First-party widget UIs (Todo, Note, Pet, Focus Coach, etc.)
45+
- `src/components/` — Shared reusable components
46+
- `src/hooks/` — Shared React hooks
47+
- `src/stores/` — Zustand state stores
48+
- `src/services/tauriApi.ts` — All Tauri command wrappers
49+
- `src/types/index.ts` — Shared TypeScript types
50+
- `src/i18n/locales/` — Translation JSON files (`en`, `zh-CN`, `zh-TW`, `ja`, `ko`, `de`, `fr`, `es`)
51+
- `src/styles/globals.css` — Tailwind entry + custom glassmorphism utilities
52+
53+
### Backend (`src-tauri/src/`)
54+
55+
- `commands/` — Tauri command handlers
56+
- `db/` — SQLite schema, migrations, and query helpers
57+
- `models/` — Shared Rust data models
58+
- `monitor/` — Active window / screen-time monitoring
59+
- `widget_registry.rs` — Widget manifest loading and normalization
60+
61+
### Widgets
62+
63+
Widgets are loaded as separate Tauri webview windows. Official widgets live in `src/widgets/`. Third-party widgets can be imported from local directories.
64+
65+
Each widget receives a `widgetId` prop. Use it to namespace `localStorage` keys (e.g. `${widgetId}-notes`).
66+
67+
## Conventions
68+
69+
### Code Style
70+
71+
- Use **functional components** and hooks.
72+
- Prefer `clsx` for conditional class names.
73+
- Keep UI text in `i18n` JSON files; never hardcode user-facing strings.
74+
- Add new i18n keys to `en` and `zh-CN` first; use English stubs for other languages unless you can translate accurately.
75+
- Use the existing `glass-card`, `ui-field`, `ui-checkbox`, `btn-primary` utilities instead of inventing new styles.
76+
77+
### Backend
78+
79+
- Tauri commands return `Result<T, String>` for user-facing errors.
80+
- Database access goes through `DbState` (a `Mutex<Connection>`).
81+
- New tables need a migration in `src-tauri/src/db/migrations.rs`.
82+
- When changing Rust models, update any hand-constructed instances in tests and commands.
83+
84+
### Cross-Window Events
85+
86+
Inside a widget, `window.dispatchEvent` only reaches the same window. To notify other widget windows or the main app, use Tauri events:
87+
88+
```ts
89+
import { emit } from "@tauri-apps/api/event";
90+
import { listen } from "@tauri-apps/api/event";
91+
```
92+
93+
### Error Handling in Widgets
94+
95+
Use the `useWidgetErrorReporter` hook to automatically record unhandled errors to the per-widget error log:
96+
97+
```ts
98+
import { useWidgetErrorReporter } from "@/hooks/useWidgetErrorReporter";
99+
100+
export default function MyWidget({ widgetId }: Props) {
101+
useWidgetErrorReporter(widgetId);
102+
// ...
103+
}
104+
```
105+
106+
## Localization Checklist
107+
108+
When adding user-facing text:
109+
110+
1. Add key to `src/i18n/locales/en/<namespace>.json`
111+
2. Add key to `src/i18n/locales/zh-CN/<namespace>.json`
112+
3. Add English stub to `src/i18n/locales/{es,de,fr,ko,ja,zh-TW}/<namespace>.json`
113+
114+
Namespaces include: `common`, `dashboard`, `widgets`, `settings`, `limits`, `categories`, `goals`, `focus`, `browserUsage`.
115+
116+
## Version Bumps
117+
118+
When bumping the app version, update all of these:
119+
120+
- `package.json`
121+
- `package-lock.json` (top-level + root package entries)
122+
- `src-tauri/Cargo.toml`
123+
- `src-tauri/tauri.conf.json`
124+
- `src-tauri/Cargo.lock` (run `cargo update -p timelens` from `src-tauri/`)
125+
- `src-tauri/windows/Package.appxmanifest`
126+
- `CHANGELOG.md`
127+
128+
The `src/version.ts` file re-exports `package.json` version, so it does not need manual editing.
129+
130+
## Common Pitfalls
131+
132+
- **Date parsing**: Backend stores local datetimes as `YYYY-MM-DDTHH:MM:SS`. Parsing with `new Date()` can interpret them as UTC and shift by the local timezone offset. Use a local-component parser when computing durations.
133+
- **Dropdown z-index**: `ExePickerInput` and similar popovers may render under later cards. Increase `z-index` on both the wrapper and the popup if needed.
134+
- **Widget window events**: Each widget is its own window; use Tauri `emit`/`listen` for cross-widget communication.
135+
- **Focus rules**: Frontend `FocusRule` does not include `created_at`; the backend model must keep it optional to avoid deserialization failures.
136+
- **Cargo lockfile**: After editing `Cargo.toml`, run `cargo update -p timelens` instead of a full `cargo update` to avoid unnecessary dependency churn.
137+
138+
## Release Notes
139+
140+
Add a new section to `CHANGELOG.md` for every version bump. Follow the existing Keep a Changelog format with `Added`, `Changed`, and `Fixed` subsections.

CHANGELOG.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,31 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
55

66
---
77

8+
## [2.0.5] - 2026-08-26
9+
10+
### Added
11+
12+
- **Widget Center two-column layout** — official widgets and third-party widgets now scroll independently, with a subtler divider and proper edge padding so the left column is no longer clipped.
13+
- **Cross-window Quick Capture refresh** — capturing a todo or note from the Quick Capture widget now broadcasts a Tauri event, so open Todo and Note widgets refresh automatically.
14+
- **Widget error reporter** — added `useWidgetErrorReporter` hook that catches unhandled errors and promise rejections in first-party widgets and records them to the per-widget error log with recovery hints.
15+
- **Error log filtering** — the Widget Center error log panel now has a real-time filter input.
16+
- **Settings auto-blur modal** — turning on "Fade widgets when unfocused" now opens a modal where users can choose which widgets auto-blur; the choice is persisted per widget and editable later from the same settings card.
17+
18+
### Changed
19+
20+
- **Pet widget rewrite** — simplified the desktop pet into a cleaner companion view with import success/error feedback and integrated error reporting.
21+
- **Focus rule save UX** — the Focus Mode rule form now validates required fields, shows a loading state, and displays success or error messages after saving.
22+
23+
### Fixed
24+
25+
- **Focus Coach timer showing `-2` / freezing** — the widget now parses backend local datetimes as local time instead of UTC, preventing negative durations. The timer also starts counting immediately and the button label updates right away.
26+
- **Focus Coach button state** — "Start Focus" now correctly becomes "Stop Focus" after a session is started.
27+
- **Focus rule "Add rule" not working** — the backend `FocusRule` model now accepts an optional `created_at`, so rules submitted from the frontend save successfully instead of failing deserialization.
28+
- **Goals and Categories dropdown layering** — the app/executable picker dropdown now renders above subsequent cards instead of being clipped underneath.
29+
- **Widget auto-blur and permission item backgrounds** — lowered the background opacity of per-widget items in Settings for a lighter appearance.
30+
31+
---
32+
833
## [2.0.2] - 2026-07-27
934

1035
### Added

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@ Please read [CONTRIBUTING.md](CONTRIBUTING.md) before submitting pull requests.
167167
## 🗺 Roadmap
168168

169169
- [Unified Roadmap](docs/ROADMAP.md)
170+
- [Widget Runtime Rewrite Roadmap (Proposed)](docs/ROADMAP_WIDGET_RUNTIME_REWRITE.md)
171+
- [Widget Runtime Rewrite Implementation Plan (Draft)](docs/WIDGET_RUNTIME_REWRITE_IMPLEMENTATION_PLAN.md)
170172

171173
---
172174

README_zh.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,8 @@ TimeLens/
165165
## 🗺 路线图
166166

167167
- [统一路线图](docs/ROADMAP.md)
168+
- [小组件底层重写专项路线图(提案)](docs/ROADMAP_WIDGET_RUNTIME_REWRITE.md)
169+
- [小组件底层重写详细实施方案(草案)](docs/WIDGET_RUNTIME_REWRITE_IMPLEMENTATION_PLAN.md)
168170

169171
---
170172

0 commit comments

Comments
 (0)