aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorwinter2025-01-26 16:24:10 +0000
committerwinter2025-01-26 16:24:10 +0000
commite8106abb8006f5e60e1f2d42621c64ae3d78e372 (patch)
tree04bb030cdba4043794eb7136b5ca24fd8e81886d
parent890dad24d6c095c41e6358b2a6cb61f1b6c2f6ad (diff)
infinite scroll
-rw-r--r--Digitigrade/Timeline/Timeline.php2
-rw-r--r--locale/en_GB.json1
-rw-r--r--routes/timelines.php44
-rw-r--r--static/skeleton.css3
-rw-r--r--templates/infinite_scroll_trigger.php10
-rw-r--r--templates/timeline.php1
6 files changed, 42 insertions, 19 deletions
diff --git a/Digitigrade/Timeline/Timeline.php b/Digitigrade/Timeline/Timeline.php
index f53eaa4..0951609 100644
--- a/Digitigrade/Timeline/Timeline.php
+++ b/Digitigrade/Timeline/Timeline.php
@@ -6,7 +6,7 @@ use Digitigrade\Model\UserAccount;
abstract class Timeline {
// TODO: currently making this number up. probably should be modifiable somewhere
- private const RESULTS_PER_PAGE = 50;
+ private const RESULTS_PER_PAGE = 20;
/**
* Gets a pageful of items to be included in the timeline
diff --git a/locale/en_GB.json b/locale/en_GB.json
index 41798d5..233860c 100644
--- a/locale/en_GB.json
+++ b/locale/en_GB.json
@@ -43,6 +43,7 @@
"placeholder": "There's nothing here.",
"placeholder.moreItems": "…and %d more",
"placeholder.noMoreItems": "No more items.",
+ "placeholder.loadingMore": "Loading more…",
"navigation.login": "Log in",
"navigation.logout": "Log out",
"navigation.logout.confirmation": "Are you sure you want to log out?",
diff --git a/routes/timelines.php b/routes/timelines.php
index f70c0d6..8bd2873 100644
--- a/routes/timelines.php
+++ b/routes/timelines.php
@@ -1,30 +1,40 @@
<?php
use Digitigrade\HttpResponseStatus\BadRequest;
-use Digitigrade\HttpResponseStatus\TemporaryRedirect;
use Digitigrade\Model\UserAccount;
use Digitigrade\Router;
use Digitigrade\Timeline\GlobalTimeline;
use Digitigrade\Timeline\HomeTimeline;
use Digitigrade\Timeline\LocalTimeline;
-Router::getInstance()->mount('/feed/global', function (array $args) {
- $items = (new GlobalTimeline())->getPage();
- render_template('timeline', ['kind' => 'global', 'items' => $items]);
-});
-
-Router::getInstance()->mount('/feed/local', function (array $args) {
- $items = (new LocalTimeline())->getPage();
- render_template('timeline', ['kind' => 'local', 'items' => $items]);
-});
-
-Router::getInstance()->mount('/feed/home', function (array $args) {
- $user = UserAccount::findByCurrentSession();
- if ($user == null) {
- throw new TemporaryRedirect('/feed/global');
+Router::getInstance()->mount('/feed/:kind', function (array $args) {
+ /** @var \Digitigrade\Timeline\Timeline $provider */
+ $provider = match ($args['kind']) {
+ 'global' => new GlobalTimeline(),
+ 'local' => new LocalTimeline(),
+ 'home' => new HomeTimeline(UserAccount::requireByCurrentSession())
+ };
+ $page = $_GET['page'] ?? 0;
+ $items = $provider->getPage($page);
+ if (isset($_GET['infinite'])) {
+ // infinite scroll update
+ if (count($items) > 0) {
+ foreach ($items as $item) {
+ $item->getReason()?->renderAsHtml();
+ $item->getObject()->renderAsHtml();
+ }
+ render_template('infinite_scroll_trigger', [
+ 'kind' => $args['kind'],
+ 'isUpdate' => true,
+ 'nextPage' => $page + 1
+ ]);
+ } else {
+ render_template('infinite_scroll_trigger', ['isEnd' => true]);
+ }
+ } else {
+ // regular timeline page
+ render_template('timeline', ['kind' => $args['kind'], 'items' => $items]);
}
- $items = (new HomeTimeline($user))->getPage();
- render_template('timeline', ['kind' => 'home', 'items' => $items]);
});
Router::getInstance()->mount('/feed/home/partial', function (array $args) {
diff --git a/static/skeleton.css b/static/skeleton.css
index 4b94ca5..bc08f7b 100644
--- a/static/skeleton.css
+++ b/static/skeleton.css
@@ -25,6 +25,7 @@ header {
align-items: center;
width: 100%;
box-sizing: border-box;
+ z-index: 100;
}
#siteTitle {
@@ -132,7 +133,7 @@ main {
#leftPane,
#rightPane {
position: sticky;
- top: 56px;
+ top: 72px;
height: max-content;
}
@media (width < 1200px) {
diff --git a/templates/infinite_scroll_trigger.php b/templates/infinite_scroll_trigger.php
new file mode 100644
index 0000000..dce1343
--- /dev/null
+++ b/templates/infinite_scroll_trigger.php
@@ -0,0 +1,10 @@
+<?php if ($isEnd): ?>
+ <div id="infiniteScroll" hx-swap-oob="true">
+ <?php call_template('placeholder_text', ['count' => 0]); ?>
+ </div>
+<?php else: ?>
+ <div id="infiniteScroll" hx-trigger="intersect" hx-get="/feed/<?= $kind ?>?page=<?= $nextPage ?>&infinite=true"
+ hx-target="previous #timelineItems" hx-swap="beforeend" <?= ($isUpdate ?? false) ? 'hx-swap-oob="true"' : '' ?>>
+ <?php call_template('placeholder_text', ['message' => 'Loading more…']); ?>
+ </div>
+<?php endif; ?> \ No newline at end of file
diff --git a/templates/timeline.php b/templates/timeline.php
index a65b4ce..a517c6f 100644
--- a/templates/timeline.php
+++ b/templates/timeline.php
@@ -17,4 +17,5 @@
$item->getObject()->renderAsHtml();
}
echo '</div>';
+ call_template('infinite_scroll_trigger', ['kind' => $kind, 'nextPage' => 1]);
}); \ No newline at end of file