Skip to content

Commit cf7f6c8

Browse files
committed
feat(demo): add UID-based load-more pagination and lazy message hydration
1 parent 8ac612f commit cf7f6c8

File tree

3 files changed

+342
-61
lines changed

3 files changed

+342
-61
lines changed

example/get.php

Lines changed: 76 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@
2424
$messageUid = null;
2525
}
2626
$messageAction = $_GET['action'] ?? null;
27+
$messageDetails = isset($_GET['details']) && '1' === (string) $_GET['details'];
28+
$beforeUid = isset($_POST['before_uid']) ? (int) $_POST['before_uid'] : null;
29+
if (null !== $beforeUid && $beforeUid <= 0) {
30+
$beforeUid = null;
31+
}
2732

2833
$bodyLength = (int) ($_POST['body_length'] ?? 500);
2934
if ($bodyLength < 100) {
@@ -47,23 +52,39 @@
4752
$_POST['mailbox'] ?: '{imap.gmail.com:993/imap/ssl}INBOX',
4853
$username,
4954
$password
50-
)
51-
->fields([
52-
'uid',
53-
'subject',
54-
'from',
55-
'to',
56-
'cc',
57-
'replyTo',
58-
'date',
59-
'textBody',
60-
'htmlBody',
61-
'attachments',
62-
'seen',
63-
'answered',
64-
'size',
65-
'preview',
66-
])
55+
);
56+
57+
$listFields = [
58+
'uid',
59+
'subject',
60+
'from',
61+
'to',
62+
'cc',
63+
'replyTo',
64+
'date',
65+
'seen',
66+
'answered',
67+
'size',
68+
];
69+
70+
$detailFields = [
71+
'uid',
72+
'subject',
73+
'from',
74+
'to',
75+
'cc',
76+
'replyTo',
77+
'date',
78+
'textBody',
79+
'htmlBody',
80+
'attachments',
81+
'seen',
82+
'answered',
83+
'size',
84+
];
85+
86+
$imap
87+
->fields($messageDetails ? $detailFields : $listFields)
6788
->limit((int) ($_POST['limit'] ?? 10))
6889
->orderBy('desc');
6990

@@ -137,10 +158,17 @@
137158
};
138159

139160
$formatMessage = static function (array $msg) use ($bodyLength, $mapAddresses) {
140-
// Use the built-in preview which handles text/HTML fallback and whitespace
141-
$body = $msg['preview'] ?? '';
142-
$bodyPreview = mb_substr($body, 0, $bodyLength);
143-
$isTruncated = mb_strlen($body) > $bodyLength;
161+
$textBody = trim((string) ($msg['textBody'] ?? ''));
162+
$htmlBody = isset($msg['htmlBody']) ? (string) $msg['htmlBody'] : null;
163+
$body = $textBody;
164+
165+
if ('' === $body && null !== $htmlBody && '' !== $htmlBody) {
166+
$body = trim(strip_tags($htmlBody));
167+
}
168+
169+
$bodyPreview = '' !== $body ? mb_substr($body, 0, $bodyLength) : '';
170+
$isTruncated = '' !== $body && mb_strlen($body) > $bodyLength;
171+
$hasDetails = array_key_exists('textBody', $msg) || array_key_exists('htmlBody', $msg);
144172

145173
$size = (int) ($msg['size'] ?? 0);
146174
if ($size >= 1048576) {
@@ -164,7 +192,8 @@
164192
'bodyPreview' => $bodyPreview,
165193
'bodyFull' => $body,
166194
'bodyTruncated' => $isTruncated,
167-
'htmlBody' => $msg['htmlBody'] ?? null,
195+
'htmlBody' => $htmlBody,
196+
'detailsLoaded' => $hasDetails,
168197
'seen' => (bool) ($msg['seen'] ?? false),
169198
'answered' => (bool) ($msg['answered'] ?? false),
170199
'size' => $size,
@@ -210,19 +239,40 @@
210239
exit;
211240
}
212241

213-
$messages = $imap->getMessages();
242+
$listOverrides = [];
243+
if (null !== $beforeUid) {
244+
$listOverrides['before_uid'] = $beforeUid;
245+
}
246+
247+
$messages = $imap->getMessages($listOverrides);
214248

215249
// Format for frontend
216250
$output = array_map($formatMessage, $messages);
217251

218-
// Get total count matching criteria (without limit)
219-
$totalFound = $imap->getTotalCount($imap->getConfig()->toImapCriteria());
252+
// Get counts for UI and pagination
253+
$baseCriteria = $imap->getConfig()->toImapCriteria();
254+
$effectiveConfig = [] !== $listOverrides ? $imap->getConfig()->merge($listOverrides) : $imap->getConfig();
255+
$pagedCriteria = $effectiveConfig->toImapCriteria();
256+
$totalFound = $imap->getTotalCount($baseCriteria);
257+
$remainingForCursor = $imap->getTotalCount($pagedCriteria);
258+
$hasMore = $remainingForCursor > count($output);
259+
$nextBeforeUid = null;
260+
if ([] !== $output) {
261+
$uids = array_column($output, 'uid');
262+
$lowestUid = (int) min($uids);
263+
if ($lowestUid > 1) {
264+
$nextBeforeUid = $lowestUid - 1;
265+
}
266+
}
220267

221268
echo json_encode([
222269
'success' => true,
223270
'count' => count($output),
224271
'totalFound' => $totalFound,
225-
'searchCriteria' => $imap->getConfig()->toImapCriteria(),
272+
'remainingForCursor' => $remainingForCursor,
273+
'hasMore' => $hasMore,
274+
'nextBeforeUid' => $nextBeforeUid,
275+
'searchCriteria' => $baseCriteria,
226276
'messages' => $output,
227277
], JSON_INVALID_UTF8_SUBSTITUTE);
228278

0 commit comments

Comments
 (0)