Skip to content

Commit 30fea23

Browse files
committed
feat: add global link analytics, like button & live presence (Firestore)
- New link-analytics.js module: click badges, likes, views, live readers - Floating 👍 like button with spring+fade-out animation on click - Like button lifted above shared-view pill to avoid overlap - Inline click count badges on all preview links (global via Firestore FieldValue.increment) - Analytics panel (slide-in right) with ranked link list + bar chart - Live 'X reading now' presence via Firestore onSnapshot/heartbeat (20s TTL 60s) - Document view counter per session for shared docs - Firestore rules: link_clicks collection + readers subcollection - Fixed module load order: standalone try/catch after Phase 3a - Fixed init timing: waitForPreview() poll replaces readyState check
1 parent 218d9f3 commit 30fea23

5 files changed

Lines changed: 1160 additions & 0 deletions

File tree

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Link Analytics — Global Click Tracking, Likes & Live Presence
2+
3+
- Added `js/link-analytics.js` — new module for global cross-user analytics via Firestore
4+
- Added `css/link-analytics.css` — styles for like widget, click badges, and analytics panel
5+
- Click count badges appear inline next to each `<a>` link in the preview pane
6+
- Badge counts are global (shared across ALL users) via Firestore `link_clicks` collection using `FieldValue.increment()`
7+
- Badges seeded instantly from localStorage display cache; refreshed from Firestore in background
8+
- Added floating 👍 Like button (fixed, bottom-right) — one like per session, saved to Firestore
9+
- Like button disappears with a spring-bump → fade-out animation after being clicked
10+
- Fixed: like button lifted above shared-view pill when `body.shared-view-active` to prevent overlap
11+
- Fixed: like button lifts above composer FAB on mobile (`bottom: 80px` on ≤768px)
12+
- Added live "X reading now" presence tracking via Firestore heartbeat/onSnapshot (20s heartbeat, 60s TTL)
13+
- Added document view counter — increments once per session for shared docs (`link_clicks/views_{docId}`)
14+
- Added analytics panel (slide-in from right) showing ranked link list with bar chart, opened via toolbar button
15+
- Panel shows: total opens, live reader count, per-link click count + last clicked date
16+
- Added `link_clicks` Firestore collection rules (open read/write for analytics, presence subcollection)
17+
- Fixed: moved `link-analytics.js` out of `Promise.all` Phase 3a into its own `try/catch` await after Phase 3a
18+
- Fixed: replaced fragile `readyState` bootstrap with `waitForPreview()` poll (100ms × 100 retries) to handle async module load order
19+
- Updated `src/main.js` to import `link-analytics.css` and load `link-analytics.js`
20+
- Updated `firestore.rules` to allow `link_clicks` collection and `readers` subcollection
21+
22+
---
23+
24+
## Summary
25+
Implements a complete global analytics system for TextAgent shared documents. All metrics (link clicks, likes, document views, live readers) are stored in Firestore and shared across every user — not scoped to a single browser session.
26+
27+
---
28+
29+
## 1. Global Link Click Tracking
30+
**Files:** `js/link-analytics.js`, `css/link-analytics.css`
31+
**What:** Intercepts clicks on all `<a>` links in the markdown preview. Each click atomically increments a Firestore counter (`FieldValue.increment(1)`) under `link_clicks/{urlSHA256}`. A small pill badge renders inline after the link text showing the global click count.
32+
**Impact:** Any user clicking a link in any TextAgent document contributes to a shared click count visible to everyone.
33+
34+
## 2. Floating Like Button
35+
**Files:** `js/link-analytics.js`, `css/link-analytics.css`
36+
**What:** Injects a fixed-position 👍 button (bottom-right) into the preview pane. One like per browser session (memory-only dedup). Saves to `link_clicks/likes_{shareDocId}` with Firestore realtime listener for live count. On click: spring animation → fade-out → `display:none`.
37+
**Impact:** Readers of shared documents can express appreciation. Like count updates in realtime across all viewers.
38+
39+
## 3. Live Presence (Reading Now)
40+
**Files:** `js/link-analytics.js`
41+
**What:** When a shared doc is opened, writes a heartbeat document to `link_clicks/presence_{docId}/readers/{sessionId}` every 20s. A Firestore `onSnapshot` listener counts sessions with `lastSeen` within 60s and updates the green pulsing "X reading now" pill in the analytics panel header.
42+
**Impact:** Shows how many people are actively reading a shared document right now, in realtime.
43+
44+
## 4. Document View Counter
45+
**Files:** `js/link-analytics.js`
46+
**What:** On first load of a shared doc per session, increments `link_clicks/views_{docId}.views` in Firestore. Displayed in the analytics panel as "N total opens".
47+
**Impact:** Authors can see total lifetime opens of their shared documents.
48+
49+
## 5. Analytics Panel
50+
**Files:** `js/link-analytics.js`, `css/link-analytics.css`
51+
**What:** Slide-in right panel (420px wide, keyboard-dismissable) opened via a bar chart toolbar button. Fetches all click data from Firestore, renders a ranked list with proportional bars (gold/silver/bronze for top 3), total opens, and live reader count.
52+
**Impact:** Central dashboard for all link and document engagement metrics.
53+
54+
## 6. Firestore Rules
55+
**Files:** `firestore.rules`
56+
**What:** Added `link_clicks/{docId}` collection rules (open read/write) and `readers/{sessionId}` subcollection rules (write limited to `{lastSeen: int}` shape, delete allowed for cleanup).
57+
**Impact:** Enables anonymous read/write for analytics without touching the protected `shares` collection rules.
58+
59+
## 7. Module Load Fix
60+
**Files:** `src/main.js`, `js/link-analytics.js`
61+
**What:** Extracted from `Promise.all` Phase 3a into a standalone `try/catch await` after Phase 3a. Replaced `readyState` bootstrap with `waitForPreview()` — a 100ms polling loop that waits up to 10s for `M.markdownPreview`, `M.renderMarkdown`, and `M.db` to be available.
62+
**Impact:** Eliminates silent initialization failures when the module loads before the preview element is wired.
63+
64+
---
65+
66+
## Files Changed (4 total)
67+
68+
| File | Type | Description |
69+
|------|------|-------------|
70+
| `js/link-analytics.js` | NEW | Core analytics module (~570 lines) |
71+
| `css/link-analytics.css` | NEW | All styles for badges, like widget, panel |
72+
| `src/main.js` | MODIFIED | CSS import + standalone module load |
73+
| `firestore.rules` | MODIFIED | `link_clicks` collection + presence rules |

0 commit comments

Comments
 (0)