Skip to content

Commit eca864e

Browse files
committed
Quote taps scroll to post on current page when possible, and cross-page jumps now are no longer overridden by unread posts destination
1 parent 05e0f08 commit eca864e

3 files changed

Lines changed: 41 additions & 9 deletions

File tree

App/Resources/RenderView.js

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1286,13 +1286,28 @@ Awful.isSpoiled = function(element) {
12861286

12871287

12881288
/**
1289-
Scrolls the identified post into view.
1289+
Scrolls the identified post into view, accounting for the navigation bar inset
1290+
(`topOffset`) and animating when `animated` is true. Falls back to hash navigation
1291+
when the element isn't in the DOM (so a late-arriving post can still resolve).
12901292
*/
1291-
Awful.jumpToPostWithID = function(postID) {
1292-
// If we previously jumped to this post, we need to clear the hash in order to jump again.
1293-
window.location.hash = "";
1293+
Awful.jumpToPostWithID = function(postID, animated, topOffset) {
1294+
var post = document.getElementById(postID);
1295+
if (!post) {
1296+
// If we previously jumped to this post, clear the hash so the same target jumps again.
1297+
window.location.hash = "";
1298+
window.location.hash = `#${postID}`;
1299+
return;
1300+
}
12941301

1295-
window.location.hash = `#${postID}`;
1302+
var rect = post.getBoundingClientRect();
1303+
var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
1304+
var targetPosition = rect.top + scrollTop - (topOffset || 0);
1305+
1306+
if (animated) {
1307+
window.scrollTo({ top: targetPosition, behavior: 'smooth' });
1308+
} else {
1309+
window.scrollTo(0, targetPosition);
1310+
}
12961311
};
12971312

12981313

App/View Controllers/Posts/PostsPageViewController.swift

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,15 @@ final class PostsPageViewController: ViewController {
363363
self.hiddenPosts = pendingHidden
364364
self.hiddenPostsAfterLoading = nil
365365
} else if self.hiddenPosts == 0, let firstUnreadPost = firstUnreadPost, firstUnreadPost > 0 {
366-
self.hiddenPosts = firstUnreadPost - 1
366+
let pendingTargetOnPage: Bool
367+
if let pendingPostID = self.jumpToPostIDAfterLoading {
368+
pendingTargetOnPage = self.posts.contains(where: { $0.postID == pendingPostID })
369+
} else {
370+
pendingTargetOnPage = false
371+
}
372+
if !pendingTargetOnPage {
373+
self.hiddenPosts = firstUnreadPost - 1
374+
}
367375
}
368376

369377
if self.suppressNextScrollFractionPreservation {
@@ -2096,6 +2104,13 @@ extension PostsPageViewController: RenderViewDelegate {
20962104
if let i = posts.firstIndex(where: { $0.postID == postID }) {
20972105
readIgnoredPostAtIndex(i)
20982106
}
2107+
} else if case let .post(id: postID, _) = route,
2108+
let i = posts.firstIndex(where: { $0.postID == postID })
2109+
{
2110+
if i < hiddenPosts {
2111+
showHiddenSeenPosts()
2112+
}
2113+
postsView.renderView.jumpToPost(identifiedBy: postID, animated: true)
20992114
} else {
21002115
AppDelegate.instance.open(route: route)
21012116
}

App/Views/RenderView.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -628,18 +628,20 @@ extension RenderView {
628628
return CGPoint(x: max(contentOffset.x, 0), y: max(contentOffset.y, 0))
629629
}
630630

631-
/// Scrolls so the identified post begins at the top of the viewport.
632-
func jumpToPost(identifiedBy postID: String) {
631+
/// Scrolls so the identified post sits below the navigation bar inset.
632+
/// Set `animated` to true for a smooth scroll.
633+
func jumpToPost(identifiedBy postID: String, animated: Bool = false) {
633634
let escapedPostID: String
634635
do {
635636
escapedPostID = try escapeForEval(postID)
636637
} catch {
637638
logger.warning("could not JSON-escape the post ID: \(error)")
638639
return
639640
}
641+
let topOffset = scrollView.contentInset.top
640642
Task {
641643
do {
642-
try await webView.eval("if (window.Awful) Awful.jumpToPostWithID(\(escapedPostID))")
644+
try await webView.eval("if (window.Awful) Awful.jumpToPostWithID(\(escapedPostID), \(animated), \(topOffset))")
643645
} catch {
644646
self.mentionError(error, explanation: "could not evaluate jumpToPostWithID")
645647
}

0 commit comments

Comments
 (0)