Skip to content

feat: @mention system with inline highlighting#20

Merged
GraysonCAdams merged 10 commits intomainfrom
feat/mentions
Mar 1, 2026
Merged

feat: @mention system with inline highlighting#20
GraysonCAdams merged 10 commits intomainfrom
feat/mentions

Conversation

@GraysonCAdams
Copy link
Copy Markdown
Collaborator

Summary

  • Add full @mention system: server-side extraction, notification preferences, MentionInput with inline highlighting, and MentionText display
  • Rework AddVideo with iMessage-style compose layout
  • Add migration conflict recovery for drizzle ORM regenerated files

Changes

  • MentionInput: Overlay input pattern with colored @mention highlights synced to scroll
  • MentionText: Validates @mentions against actual group members before highlighting
  • CommentsSheet/CommentInput: Integrated mention support
  • AddVideo: iMessage-style compose layout rework
  • DB: Migration recovery for schema conflicts on regenerated files
  • Notifications: Mention notification type in activity sheet and settings

Test plan

  • Verify @mentions highlight in blue while typing in comment input
  • Verify only valid member usernames are highlighted in MentionText
  • Verify mention dropdown appears and filters correctly
  • Verify mention notifications are created and displayed in activity
  • Verify AddVideo compose layout works correctly
  • CI passes (lint, type-check, tests, build)

- Create mentions.ts utility with extractMentions() and notifyMentions()
- Accept message field in POST /api/clips, auto-post as first comment
- Add @mention dispatch to comments API with duplicate prevention
- Update notification preferences API to include mentions toggle
- Two-field compose: Link (top) + Message (bottom) with @mention support
- Tab from URL field focuses message field
- Message auto-posted as first comment on clip
- Hide clipboard suggestion when URL input matches clipboard content
- Replace plain input with MentionInput in CommentInput
- Render @mentions with MentionText highlighting in comments/replies
- Pass group members from store to CommentsSheet via ReelItem
- Add 'mention' to Notification type union with "mentioned you" text
- Show comment preview for mention notifications in activity feed
- Add mentions toggle to notification preferences UI
- Include mentions in NotificationPrefs type and default state
Replace plain input/textarea in MentionInput with an overlay pattern
where a highlight mirror renders colored @mentions behind a transparent
input. Syncs scroll position and tracks focus state for border styling.
Update parent component styles (AddVideo, CommentInput) to target new
class names.
Only highlight @mentions that match actual group member usernames.
Pass member usernames from CommentsSheet to MentionText for validation.
Bump mention font-weight from 600 to 700 for consistency with input.
When a migration file is regenerated after being applied (e.g. after
schema change + drizzle-kit generate), drizzle sees a new timestamp
and tries to re-run it, hitting duplicate column errors. Add recovery
logic that runs each pending statement idempotently and records the
migration in the journal.

/* eslint-disable security/detect-non-literal-fs-filename */
function recoverPendingMigrations(folder: string) {
const journalPath = resolve(folder, 'meta/_journal.json');

Check warning

Code scanning / Semgrep OSS

Semgrep Finding: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal Warning

Detected possible user input going into a path.join or path.resolve function. This could possibly lead to a path traversal vulnerability, where the attacker can access arbitrary files stored in the file system. Instead, be sure to sanitize or validate user input first.
for (const entry of journal.entries) {
if (entry.when <= lastAppliedAt) continue;

const sqlFile = readFileSync(resolve(folder, `${entry.tag}.sql`), 'utf-8');

Check warning

Code scanning / Semgrep OSS

Semgrep Finding: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal Warning

Detected possible user input going into a path.join or path.resolve function. This could possibly lead to a path traversal vulnerability, where the attacker can access arbitrary files stored in the file system. Instead, be sure to sanitize or validate user input first.
for (const entry of journal.entries) {
if (entry.when <= lastAppliedAt) continue;

const sqlFile = readFileSync(resolve(folder, `${entry.tag}.sql`), 'utf-8');

Check warning

Code scanning / Semgrep OSS

Semgrep Finding: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal Warning

Detected possible user input going into a path.join or path.resolve function. This could possibly lead to a path traversal vulnerability, where the attacker can access arbitrary files stored in the file system. Instead, be sure to sanitize or validate user input first.
@GraysonCAdams GraysonCAdams merged commit daad8b3 into main Mar 1, 2026
13 checks passed
@GraysonCAdams GraysonCAdams deleted the feat/mentions branch March 1, 2026 07:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants