From 982b7010f2a896eb1e7d62854ef7b33525fa394a Mon Sep 17 00:00:00 2001 From: Eva Date: Sun, 30 Mar 2025 03:37:25 +0200 Subject: [PATCH 1/2] client/api: don't call progress.done() on noProgress requests It would cause the progress bar to disappear completely, and not render anymore after any noProgress request. --- client/js/api.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/client/js/api.js b/client/js/api.js index 5bde6d81..7846d47b 100644 --- a/client/js/api.js +++ b/client/js/api.js @@ -439,14 +439,18 @@ class Api extends events.EventTarget { abortFunction = () => { req.abort(); // does *NOT* call the callback passed in .end() - progress.done(); + if (!options.noProgress) { + progress.done(); + } reject( new Error("The request was aborted due to user cancel.") ); }; req.end((error, response) => { - progress.done(); + if (!options.noProgress) { + progress.done(); + } abortFunction = () => {}; if (error) { if (response && response.body) { From c7f0298a3d7144116189b2b155973c44aa69fe9e Mon Sep 17 00:00:00 2001 From: Eva Date: Sun, 30 Mar 2025 03:40:46 +0200 Subject: [PATCH 2/2] client/posts: preload nearby posts for snappier browsing --- client/js/controllers/post_main_controller.js | 25 ++++++++++++++----- client/js/models/post.js | 4 +-- client/js/models/post_list.js | 5 ++-- client/js/util/misc.js | 10 ++++++++ 4 files changed, 34 insertions(+), 10 deletions(-) diff --git a/client/js/controllers/post_main_controller.js b/client/js/controllers/post_main_controller.js index 95cfdb52..f437c4d5 100644 --- a/client/js/controllers/post_main_controller.js +++ b/client/js/controllers/post_main_controller.js @@ -41,16 +41,29 @@ class PostMainController extends BasePostController { router.replace(url, ctx.state, false); } + const prevPostId = aroundResponse.prev + ? aroundResponse.prev.id + : null; + const nextPostId = aroundResponse.next + ? aroundResponse.next.id + : null; + + // preload nearby posts + if (prevPostId) { + Post.get(prevPostId, { noProgress: true }).then(misc.preloadPostImages); + PostList.getAround(prevPostId, parameters ? parameters.query : null, { noProgress: true }); + } + if (nextPostId) { + Post.get(nextPostId, { noProgress: true }).then(misc.preloadPostImages); + PostList.getAround(nextPostId, parameters ? parameters.query : null, { noProgress: true }); + } + this._post = post; this._view = new PostMainView({ post: post, editMode: editMode, - prevPostId: aroundResponse.prev - ? aroundResponse.prev.id - : null, - nextPostId: aroundResponse.next - ? aroundResponse.next.id - : null, + prevPostId: prevPostId, + nextPostId: nextPostId, canEditPosts: api.hasPrivilege("posts:edit"), canDeletePosts: api.hasPrivilege("posts:delete"), canFeaturePosts: api.hasPrivilege("posts:feature"), diff --git a/client/js/models/post.js b/client/js/models/post.js index 2fb3d34c..51e9f90c 100644 --- a/client/js/models/post.js +++ b/client/js/models/post.js @@ -199,8 +199,8 @@ class Post extends events.EventTarget { return returnedPromise; } - static get(id) { - return api.get(uri.formatApiLink("post", id)).then((response) => { + static get(id, options) { + return api.get(uri.formatApiLink("post", id), options).then((response) => { return Promise.resolve(Post.fromResponse(response)); }); } diff --git a/client/js/models/post_list.js b/client/js/models/post_list.js index 8c2c9d4e..ffee173d 100644 --- a/client/js/models/post_list.js +++ b/client/js/models/post_list.js @@ -7,12 +7,13 @@ const AbstractList = require("./abstract_list.js"); const Post = require("./post.js"); class PostList extends AbstractList { - static getAround(id, searchQuery) { + static getAround(id, searchQuery, options) { return api.get( uri.formatApiLink("post", id, "around", { query: PostList._decorateSearchQuery(searchQuery || ""), fields: "id", - }) + }), + options ); } diff --git a/client/js/util/misc.js b/client/js/util/misc.js index 756ad84b..ff64dd5a 100644 --- a/client/js/util/misc.js +++ b/client/js/util/misc.js @@ -211,6 +211,15 @@ function getPrettyName(tag) { return tag; } +function preloadPostImages(post) { + if (!["image", "animation"].includes(post.type)) { + return; + } + const img = new Image() + img.fetchPriority = "low"; + img.src = post.contentUrl; +} + module.exports = { range: range, formatRelativeTime: formatRelativeTime, @@ -229,4 +238,5 @@ module.exports = { escapeSearchTerm: escapeSearchTerm, dataURItoBlob: dataURItoBlob, getPrettyName: getPrettyName, + preloadPostImages: preloadPostImages, };