mirror of
https://github.com/RetroShare/RetroShare.git
synced 2026-09-14 11:06:01 +05:00
fix(gui): channel grid randomly blank after adding a post
Adding a post to a channel sometimes left the grid empty; switching to another channel and back made the posts reappear. The model data was always correct, but the *view* was corrupted by malformed Qt model signals emitted on the incremental single-post path. RsGxsChannelPostsModel::updateSinglePost() emitted its own layoutAboutToBeChanged() and then called updateFilter(), which emitted a second layoutAboutToBeChanged()/layoutChanged() pair. That left one layoutAboutToBeChanged() unmatched, so the attached grid view stayed in a "layout changing" state. On top of that, updateFilter() faked a full beginInsertRows(0, rowCount()-1)/endInsertRows() over rows that already existed, lying to the view about the model structure. Whether this blanked the viewport depended on grid geometry (post count modulo the column count) and async/repaint timing, hence the intermittent behaviour. A full model reset (beginResetModel in initEmptyHierarchy, triggered by switching channels) always rebuilt the view correctly, which is why the workaround worked. Fix: emit a single balanced layout-change (preMods()/postMods()) and drop the bogus beginInsertRows(). layoutChanged() is the correct signal for the row<->post reflow that std::sort() produces. Also reset the active filter in initEmptyHierarchy() (run by setPosts() on every full reload): the widget clears the search box silently (whileBlocking) without notifying the model, so a filter left over from a previously viewed channel was otherwise re-applied by updateFilter() on the next incoming post and could hide every post. Placing the reset in initEmptyHierarchy() keeps the fix self-contained and independent of how setPosts() is implemented. Boards (Posted) carried the same beginInsertRows() anti-pattern in setFilter() and setPosts(); the lie-to-the-view is removed there too for correctness and consistency. setPostsInterval() (a legitimate paginated insert/remove) is left untouched. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
6160b39dab
commit
978b30fcee
@ -223,12 +223,10 @@ void RsPostedPostsModel::setFilter(const QStringList& strings, uint32_t& count)
|
||||
|
||||
std::cerr << "After filtering: " << count << " posts remain." << std::endl;
|
||||
|
||||
if (rowCount()>0)
|
||||
{
|
||||
beginInsertRows(QModelIndex(),0,rowCount()-1);
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
// No beginInsertRows() here: the filtered set is rebuilt from scratch above, so
|
||||
// the surrounding reset + postMods() (layoutChanged) refresh the view. Faking a
|
||||
// row insertion with a mismatched range is a lie to the view (same anti-pattern
|
||||
// that could blank the channels grid) and is not needed.
|
||||
postMods();
|
||||
}
|
||||
|
||||
@ -572,12 +570,9 @@ void RsPostedPostsModel::setPosts(const RsPostedGroup& group, std::vector<RsPost
|
||||
mDisplayedNbPosts = std::min((uint32_t)mFilteredPosts.size(),mDefaultDisplayedNbPosts);
|
||||
mDisplayedStartIndex = 0;
|
||||
|
||||
if (rowCount()>0)
|
||||
{
|
||||
beginInsertRows(QModelIndex(),0,rowCount()-1);
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
// No beginInsertRows() here: setFilter() above already reset and repopulated the
|
||||
// model, so postMods() (layoutChanged) is enough. Faking a row insertion with a
|
||||
// mismatched range is the same anti-pattern that could blank the channels grid.
|
||||
postMods();
|
||||
|
||||
emit boardPostsLoaded();
|
||||
|
||||
@ -75,6 +75,15 @@ void RsGxsChannelPostsModel::initEmptyHierarchy()
|
||||
mPosts.clear();
|
||||
mFilteredPosts.clear();
|
||||
|
||||
// Reset the active filter on every (re)load. initEmptyHierarchy() is run by
|
||||
// setPosts(), and the widget clears the search box silently (whileBlocking)
|
||||
// without notifying the model; a filter left over from a previously viewed
|
||||
// channel would otherwise be re-applied by updateFilter() on the next incoming
|
||||
// post and could hide every post. Doing it here keeps the fix independent of
|
||||
// how setPosts() is implemented.
|
||||
mFilteredStrings.clear();
|
||||
mFilterUnread = false;
|
||||
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
@ -147,12 +156,12 @@ void RsGxsChannelPostsModel::updateFilter(uint32_t& count)
|
||||
|
||||
count = mFilteredPosts.size();
|
||||
|
||||
if (rowCount()>0)
|
||||
{
|
||||
beginInsertRows(QModelIndex(),0,rowCount()-1);
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
// The row<->post mapping is fully rebuilt above (posts may have been added,
|
||||
// removed or reordered by the caller), so we signal a layout change through the
|
||||
// preMods()/postMods() pair rather than faking a row insertion. Emitting
|
||||
// beginInsertRows() with a range that does not match a real insertion left the
|
||||
// attached view inconsistent and could randomly blank the grid right after a
|
||||
// post was added (only a full channel reload fixed it).
|
||||
postMods();
|
||||
}
|
||||
|
||||
@ -461,7 +470,10 @@ void RsGxsChannelPostsModel::updateSinglePost(const RsGxsChannelPost& post,std::
|
||||
added_files.clear();
|
||||
removed_files.clear();
|
||||
|
||||
emit layoutAboutToBeChanged();
|
||||
// NB: no emit layoutAboutToBeChanged() here. The single balanced layout-change
|
||||
// signal is emitted by updateFilter() below (preMods()/postMods()). Opening a
|
||||
// second, unmatched layoutAboutToBeChanged() here left the view stuck in a
|
||||
// "layout changing" state and could randomly blank the grid after a new post.
|
||||
|
||||
// linear search. Not good at all, but normally this is just for a single post.
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user