* Fix three causes of channels rendering blank
Recover a channel whose newest interval lost all its posts. A since-fetch
is the only path that receives deletions, and handlePosts destroys those
posts locally — but nothing shrinks the PostsInChannel interval they came
from. An empty interval still wins postsInChannel[0] and renders blank,
and no later since-fetch can repopulate it: once lastFetchedAt is past
the deletion the server correctly returns nothing. fetchPostsForChannel
now detects that state, drops the interval and pulls a page instead,
which merges into a surviving interval or records a real gap that closes
on scroll. Scoped to fetchOnly=false; the fetchOnly callers can leave the
same state behind but are repaired when the user opens the channel.
Thread payloads no longer advance MyChannel.lastFetchedAt. A CRT
thread-reply push carries only that thread's posts, so it is not evidence
the channel was fetched up to the reply's timestamp — advancing the
watermark let getPostsSince skip channel posts that were never fetched.
handlePosts already skips PostsInChannel for RECEIVED_IN_THREAD, and the
native handlers already guard this via receivingThreads.
Pull-to-refresh self-heals as a manual escape hatch for blank states the
automatic recovery cannot see — an interval holding only posts that get
filtered out (replies with CRT on, join/leave messages). Blankness is
measured from orderedPosts rather than posts so it accounts for those
filters.
Also fixes deletePostsForChannel, which returned early when a channel had
no posts left — precisely the post-less-interval case — and never
destroyed intervals because it called .length on a Query instead of
fetching it.
* test feedback
* fix tests
* more test fixes
(cherry picked from commit d1e1f936b6)
Co-authored-by: Elias Nahum <nahumhbl@gmail.com>