link fe: fix page loading behavior

Previously, receiving new items could "locally create" pages,
half-filled with whatever items were pushed down into them. Frontend
would see the existence of the page and assume all was well. However,
the page may have contained more items (on the backend) than just what
we pushed down.

This adds a per-page flag, "local", to indicate such pages. When display
logic sees it's set, it will send a request for the full page,
regardless of currently available data, loading in the canonical full
page as a result.
This commit is contained in:
Fang 2020-02-06 17:23:32 +01:00
parent 438d502c89
commit 2b4667eb86
No known key found for this signature in database
GPG Key ID: EB035760C1BBA972
4 changed files with 22 additions and 10 deletions

View File

@ -13,7 +13,10 @@ export class Comments extends Component {
componentDidMount() {
let page = "page" + this.props.commentPage;
if (!this.props.comments || !this.props.comments[page]) {
if (!this.props.comments ||
!this.props.comments[page] ||
this.props.comments.local[page]
) {
this.setState({requested: this.props.commentPage});
api.getCommentsPage(
this.props.path,

View File

@ -17,8 +17,11 @@ export class Links extends Component {
}
componentDidUpdate() {
let linkPage = "page" + this.props.page;
if ((this.props.page != 0) && (!this.props.links[linkPage])) {
const linkPage = "page" + this.props.page;
if ( (this.props.page != 0) &&
(!this.props.links[linkPage] ||
this.props.links.local[linkPage])
) {
api.getPage(this.props.path, this.props.page);
}
}

View File

@ -69,7 +69,7 @@ export class Root extends Component {
let channelLinks = !!links[groupPath]
? links[groupPath]
: {};
: {local: {}};
let channelComments = !!comments[groupPath]
? comments[groupPath]

View File

@ -1,5 +1,8 @@
import _ from 'lodash';
// page size as expected from link-view.
// must change in parallel with the +page-size in /app/link-view to
// ensure sane behavior.
const PAGE_SIZE = 25;
export class LinkUpdateReducer {
@ -28,12 +31,13 @@ export class LinkUpdateReducer {
// if we didn't have any state for this path yet, initialize.
if (!state.links[path]) {
state.links[path] = {};
state.links[path] = {local: {}};
}
// since data contains an up-to-date full version of the page,
// we can safely overwrite the one in state.
state.links[path][page] = here.page;
state.links[path].local[page] = false;
state.links[path].totalPages = here.totalPages;
state.links[path].totalItems = here.totalItems;
}
@ -84,13 +88,14 @@ export class LinkUpdateReducer {
state.comments[path] = {};
}
if (!state.comments[path][url]) {
state.comments[path][url] = {};
state.comments[path][url] = {local: {}};
}
let here = state.comments[path][url];
// since data contains an up-to-date full version of the page,
// we can safely overwrite the one in state.
here[page] = data.page;
here.local[page] = false;
here.totalPages = data.totalPages;
here.totalItems = data.totalItems;
}
@ -117,14 +122,15 @@ export class LinkUpdateReducer {
//
_addNewItems(items, pages = {}, page = 0) {
_addNewItems(items, pages = {local: {}}, page = 0) {
//TODO kinda want to refactor this, have it just be number indexes
const i = "page" + page;
//TODO but if there's more on the page than just the things we're
// pushing onto it, we won't load that in. should do an
// additional check (+ maybe load) on page-nav, right?
if (!pages[i]) {
pages[i] = [];
// if we know this page exists in the backend, flag it as "local",
// so that we know to initiate a "fetch the rest" request when we want
// to display the page.
pages.local[i] = (page < pages.totalPages);
}
pages[i] = items.concat(pages[i]);
pages.totalItems = pages.totalItems + items.length;