Skip to content

Add timestamp-based last-read tracking and unread divider markers#227

Open
Specter242 wants to merge 3 commits intozjs81:mainfrom
Specter242:codex/unread-last-read-timestamps
Open

Add timestamp-based last-read tracking and unread divider markers#227
Specter242 wants to merge 3 commits intozjs81:mainfrom
Specter242:codex/unread-last-read-timestamps

Conversation

@Specter242
Copy link
Contributor

@Specter242 Specter242 commented Feb 24, 2026

Summary

Adds timestamp-based last-read tracking for contacts/channels and uses it to place an in-chat unread divider for DM and channel threads.

Why

Unread counts alone are not stable for locating the unread boundary after list mutations.
Timestamp markers provide deterministic first-unread positioning while preserving count-based fallback behavior.

Changes

  • lib/storage/unread_store.dart
    • Persist/debounce contact and channel last-read timestamps.
  • lib/connector/meshcore_connector.dart
    • Store/load in-memory last-read maps.
    • Add timestamp getters:
      • contactLastReadTimestamp(...)
      • channelLastReadTimestamp(...)
    • Add first-unread helpers with fallback:
      • firstUnreadContactIndex(...)
      • firstUnreadChannelIndex(...)
    • Update read-mark APIs to persist timestamps.
    • Remove marker state when deleting contacts/channels.
  • lib/screens/chat_screen.dart
    • Render unread divider for DM threads.
  • lib/screens/channel_chat_screen.dart
    • Render unread divider for channel threads.
  • lib/widgets/unread_marker_divider.dart
    • Shared unread divider widget.

Behavior Notes

  • Divider placement prefers timestamp markers.
  • If no marker resolves to a newer message, logic falls back to unread-count behavior.
  • Existing unread counters remain intact.

Validation

  • dart format on touched files
  • flutter analyze lib/connector/meshcore_connector.dart lib/storage/unread_store.dart lib/screens/chat_screen.dart lib/screens/channel_chat_screen.dart lib/widgets/unread_marker_divider.dart (pass)

Issue

Part of #73

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8ccfe97278

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +421 to +423
if (markerIndex >= 0) return markerIndex;
return null;
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Fall back to unread count when marker scan finds nothing

When a last-read marker exists, this branch returns null if no message timestamp is greater than the marker, so the count-based fallback is never used. Because markContactRead/markChannelRead store DateTime.now() while incoming message timestamps are device-provided, clock skew or unset device time can leave unread messages with timestamps <= marker; in that case unread counts stay positive but first-unread positioning is lost (same logic is duplicated in firstUnreadChannelIndex).

Useful? React with 👍 / 👎.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 048b798.\n\nI updated both firstUnreadContactIndex and firstUnreadChannelIndex to always fall back to unread-count positioning when a timestamp marker exists but no message is newer than that marker. This keeps first-unread placement working under clock skew / device-time mismatch cases while still preferring marker-based placement when available.

@Specter242 Specter242 force-pushed the codex/unread-last-read-timestamps branch from 048b798 to 724b760 Compare February 25, 2026 17:47
@Specter242 Specter242 changed the title Add timestamp-based last-read tracking for unread state Add timestamp-based last-read tracking and unread divider markers Feb 25, 2026
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.

1 participant