What changed
Three files. Query strings and body keys live in messages.constant.ts. The rest is message-container.
| Before | Now |
|---|---|
One GET with search_key. The client split rows by featured, broadcast, and empty last message. |
One GET per open tab. tab=featured|general|broadcast for creators. Fans send tab=all. Always counts=true. |
| The left list had no next page. | Scroll down sends the last cursor. Null cursor stops. A tab change or a new search starts page 1 again. |
| Tab pills were unread sums of whatever had already loaded. | Pills read counts.featured and counts.general. The sidebar number is general + featured + broadcast. |
History POST sent timeStamp. Scroll-up was commented out. |
First page is { groupId, include_validation: true }. Next page is { groupId, cursor }. Older messages prepend and the viewport stays put. |
Permissions were a second POST to ChatUserValidation. |
First history page returns validation. Retry refetches that first page. Broadcast and followers still skip it. |
Empty search is omitted, not sent as search_key=. Opening an unread row still zeros that row and subtracts its unread from the stored counts so the pills do not bounce back until the next inbox GET.
Requests I actually saw
Logged in as Jon Snow. Network log on localhost:4202/messages.
GET api/get-chatGroups-and-users?tab=featured&counts=true
GET api/get-chatGroups-and-users?tab=general&counts=true
GET api/get-chatGroups-and-users?tab=broadcast&counts=true
GET api/get-chatGroups-and-users?tab=featured&counts=true&search_key=Noel
GET api/get-chatGroups-and-users?tab=general&counts=true&search_key=Prateek
POST api/getpreviousMessagesFromHttp
{ "groupId": "CHATGROUP#1787300718906", "include_validation": true }
Every inbox and history reply on this account had cursor: null. That is why I could prove first pages and "stop", and not the append page.
Verified
| Check | Result |
|---|---|
| Priority first page | Verified. tab=featured&counts=true, no cursor. 1 row, Noel Huber. |
| General first page | Verified. tab=general&counts=true, no cursor. 30 rows. |
| Message Lists first page | Verified. tab=broadcast&counts=true, no cursor. 0 rows, empty state. |
| Inbox response shape | Verified. data, counts, cursor on every inbox reply. |
| Counts and sidebar total | Verified. { general: 0, featured: 0, broadcast: 0 }. Messages had no sidebar badge. |
| Tab change resets the page | Verified. Each tab requested its own first page. No leftover cursor. |
| Search is a new first page | Verified. search_key=Noel on featured, search_key=Prateek on general. Clearing search dropped search_key. |
| Inbox stops on a null cursor | Verified. I scrolled the 30-row General list. No extra inbox GET. |
| History first page | Verified. Body was groupId plus include_validation: true. Reply had response, cursor, validation. |
| History stops on a null cursor | Verified. Noel Huber returned 8 messages and cursor: null. Scroll-up did not fire again. |
Not verified
The next-page code is in the component. I never saw a non-null cursor on this account, so I did not watch an append request leave the browser.
| Check | Why it is still open |
|---|---|
| Inbox next page | Not run. Need a tab whose first page returns a cursor. The next GET must keep the same tab and search and add that cursor. Rows append. No duplicate groupId. |
| History next page | Not run. Need a long thread. Next POST should be { groupId, cursor } with no include_validation. Older bubbles appear above. You stay near the same message. |
| Non-zero tab pills | Not run. All counts were 0, so I never saw a live Priority or General number. |
Fan inbox tab=all |
Not run. I only logged in as the creator. |
| Broadcast history | Not run. Message Lists was empty. That path should still send from and skip validation. |
| Unread decrement | Not run. No unread rows, so I did not watch a pill drop when a thread opened. |
Finish these on a fatter account
Same two URLs in DevTools. Disable cache. There should be no chat-user-validation when you open a normal DM.
- Find a tab with a cursor. Scroll the left list. Confirm the next GET adds that cursor and then stops when the server sends null.
- Open a long DM. Scroll to the top. Confirm the next POST is only
groupIdandcursor. - Open an unread thread. The row badge, the tab pill, and the sidebar should drop by that unread count and stay down until the next inbox GET.
- Log in as a fan. No tab UI. First GET is
tab=all&counts=true. - Open a message list. History still sends
from. Noinclude_validation. - Hit
/messages?user=someonefor a person who is not on page 1. It should still open them. - Open thread A, then B quickly. B's messages and validation win. A late A page must not prepend into B.