Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 7, 2026

Extends the existing UserNote system to support public comments, reactions, and clickable timestamps for seeking to specific song positions. Backed by Parse Server with real-time sync.

Data Layer

Realm (Local)

  • Extended UserNoteModel with IsPublic, TimestampMs, AuthorId, AuthorUsername, ReactionsJson
  • UserNoteModelView adds computed properties for timestamp display and reaction totals

Parse (Cloud)

  • New SongComment class with full feature parity plus Reactions (emoji → count) and ReactionUsers (emoji → user IDs) dictionaries
  • ACL enforces write-restricted-to-author, public-read-if-public

Service Layer

ISongCommentService / ParseSongCommentService:

  • Standard CRUD with public/private filtering
  • Reaction management (add/remove/toggle) with duplicate prevention
  • Live query subscriptions via ParseLiveQueryClient
  • Bidirectional sync between Realm and Parse
  • Helper methods extracted to eliminate duplication in reaction logic

SongCommentMapper:

  • Converts between Realm embedded objects and Parse cloud objects
  • Handles reaction serialization (simple "emoji:count,emoji:count" format for Realm)

ViewModel

SongCommentsViewModel:

  • Observable collections for public/private/all comments
  • Commands: create, update, delete, toggle reaction, seek to timestamp, sync
  • Integrates with BaseViewModel.SeekTrackPosition() for playback control
  • Timestamp picker uses AudioService.CurrentPosition

Android UI

SongNotesRecyclerViewAdapter (enhanced):

  • Timestamp chip with click-to-seek
  • Four reaction buttons with counts (👍🔥❤️😢)
  • Visibility indicator (public/private)
  • Author attribution

SongCommentDialogFragment:

  • Multi-line text input
  • Public/Private toggle via Material chips
  • "Use Current Position" button for timestamp
  • Edit and Create modes

Example Usage

// Load comments for a song
await commentsViewModel.LoadCommentsForSongAsync(song);

// Create timestamped comment
commentsViewModel.NewCommentText = "Epic guitar solo!";
commentsViewModel.NewCommentTimestamp = 92340; // 1:32.340
commentsViewModel.NewCommentIsPublic = true;
await commentsViewModel.CreateCommentCommand.ExecuteAsync(null);

// Toggle reaction
await commentsViewModel.ToggleReactionCommand.ExecuteAsync(
    (commentId: "abc123", reactionType: "fire")
);

// Seek to timestamp (triggered by tapping timestamp badge)
await commentsViewModel.OnTimestampClickCommand.ExecuteAsync(timestampMs);

Parse Server Setup Required

Database indexes needed:

  • {songId: 1, isPublic: 1} (compound)
  • {songId: 1, timestampMs: 1} (compound)
  • {author: 1}

CLP: Public read where isPublic == true, authenticated create, author-only update/delete.

Cloud Code for atomic reactions recommended (user can currently react multiple times if Parse updates race).

Not Included

  • WinUI implementation (architecture ready, ViewModel reusable)
  • Threaded replies, typing indicators, moderation tools (documented as future work)

See SONG_COMMENTS_IMPLEMENTATION.md for Parse setup, security considerations, and API reference.

Original prompt

This section details on the original issue you should resolve

<issue_title>
Feature Request: Public Song Comments, Reactions & Timestamped Notes (Parse-backed and realm too)</issue_title>
<issue_description>

Problem

Dimmer currently supports UserNote attached to a song (IList) mainly for personal annotations and search reverse-lookup.
There is no unified, cross-platform way to:

Expose public comments

React to comments

Attach clickable timestamps that trigger playback/sample events

Keep UI parity across Android & WinUI 3

This limits social/emotional interaction during listening, which is a core engagement driver.


Proposed Solution

Extend the existing UserNote concept into a first-class Song Comment system, backed by Parse Server and shared UI logic across platforms.


Data Model (Parse)

Song

{
"objectId": "...",
"title": "...",
"artist": "...",
"userNotes": [Pointer]
}

UserNote (extended)

{
"objectId": "...",
"song": Pointer,
"author": Pointer<_User>,
"text": "string",
"timestampMs": 92340, // nullable
"isPublic": true,
"reactions": {
"like": 12,
"fire": 3,
"sad": 1
},
"createdAt": "Date"
}

Notes:

timestampMs == null → general comment

Public notes act as song comments

Private notes remain personal/search-only


Functional Requirements

CRUD

Create / edit / delete own notes

Toggle isPublic

Fetch:

All public notes for a song

User’s private notes

Timestamp Interaction

Timestamp rendered as clickable UI

On click:

Seek playback to timestampMs

Fire OnSongSampleRequested(timestampMs)

Reactions

Lightweight reaction system (no separate class initially)

Atomic increment via Parse Cloud Code


UI / UX Parity (Android & WinUI 3)

Now Playing – Comments Section

Scrollable list

Timestamp badge (if present)

Reaction buttons

Live highlight when playback crosses timestamp

Fragments / Views

Android: Fragment / Compose

WinUI 3: Page / UserControl

Shared ViewModel logic (MVVM)


Parse Considerations

CLP:

Public read if isPublic == true

Write restricted to author

Index on:

song

isPublic

timestampMs


Benefits

Enables real-time emotional sharing

No third-party ToS risk (YouTube/SoundCloud)

Reuses existing UserNote system

Scales naturally with Parse


Out of Scope (for now)

Threaded replies (but to be very heavily considered)

Live typing indicators

Moderation tooling

</issue_description>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 6 commits January 7, 2026 15:51
- Extended UserNoteModel and UserNoteModelView with public/private, timestamp, author, and reactions fields
- Created SongComment Parse model with full feature set
- Implemented ISongCommentService interface
- Implemented ParseSongCommentService with CRUD, reactions, and live query support
- Created SongCommentsViewModel with full UI logic
- Registered new services and Parse class in ServiceRegistration

Co-authored-by: YBTopaz8 <41630728+YBTopaz8@users.noreply.github.com>
- Created SongCommentMapper for converting between Realm and Parse models
- Fixed ViewModel to use correct BaseViewModel methods for seeking
- Added unit tests for SongCommentView and UserNoteModelView

Co-authored-by: YBTopaz8 <41630728+YBTopaz8@users.noreply.github.com>
…estamps

- Updated SongNotesRecyclerViewAdapter with new comment features
- Added timestamp badge with click-to-seek functionality
- Added reaction buttons (like, fire, heart, sad) with counts
- Added public/private visibility indicator
- Added author display
- Improved card layout for better UX

Co-authored-by: YBTopaz8 <41630728+YBTopaz8@users.noreply.github.com>
- Created SongCommentDialogFragment for creating/editing comments
- Added public/private toggle with Material chips
- Added timestamp picker using current playback position
- Created comprehensive implementation documentation
- Documented Parse server setup, security, and usage

Co-authored-by: YBTopaz8 <41630728+YBTopaz8@users.noreply.github.com>
- Refactored reaction methods to extract helper functions and reduce duplication
- Changed visibility icons from play/pause to more appropriate view/secure icons
- Added missing using statement for Reactive Concurrency
- Improved code organization and maintainability

Co-authored-by: YBTopaz8 <41630728+YBTopaz8@users.noreply.github.com>
This PR successfully implements the song comments feature with:
- Complete data models (Realm + Parse)
- Full service layer with CRUD and reactions
- Comprehensive ViewModel with all commands
- Complete Android UI implementation
- Unit tests and documentation
- Ready for Parse backend integration

Co-authored-by: YBTopaz8 <41630728+YBTopaz8@users.noreply.github.com>
Copilot AI changed the title [WIP] Add public song comments and reactions feature Add public song comments with reactions and timestamped notes Jan 7, 2026
Copilot AI requested a review from YBTopaz8 January 7, 2026 16:06
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.

Feature Request: Public Song Comments, Reactions & Timestamped Notes (Parse-backed and realm too)

2 participants