Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic page size [non-breaking change] #375

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/configuration-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,11 @@ export class ConfigurationComponent {
</p>
<div class="config-field" id="script" class="highlight highlight-text-html-basic"></div>
<button id="copy-button" type="button" class="btn btn-blue code-action">Copy</button>

<p>There is an <em>optional</em> argument <code>size</code> that specifies the number of comments to be displayed before the
rest are folded. The default value is 25. For example, <code>size=2</code> will format the timeline as two comments,
expand button, then at most three other comments.
</p>
<br/>
<br/>`;

Expand Down
10 changes: 4 additions & 6 deletions src/github.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ const GITHUB_ENCODING__HTML_JSON = 'application/vnd.github.VERSION.html+json';
const GITHUB_ENCODING__HTML = 'application/vnd.github.VERSION.html';
const GITHUB_ENCODING__REACTIONS_PREVIEW = 'application/vnd.github.squirrel-girl-preview';

export const PAGE_SIZE = 25;

export type ReactionID = '+1' | '-1' | 'laugh' | 'hooray' | 'confused' | 'heart' | 'rocket' | 'eyes';

export const reactionTypes: ReactionID[] = ['+1', '-1', 'laugh', 'hooray', 'confused', 'heart', 'rocket', 'eyes'];
Expand Down Expand Up @@ -168,16 +166,16 @@ export function loadIssueByNumber(issueNumber: number) {
});
}

function commentsRequest(issueNumber: number, page: number) {
const url = `repos/${owner}/${repo}/issues/${issueNumber}/comments?page=${page}&per_page=${PAGE_SIZE}`;
function commentsRequest(issueNumber: number, page: number, size: number) {
const url = `repos/${owner}/${repo}/issues/${issueNumber}/comments?page=${page}&per_page=${size}`;
const request = githubRequest(url);
const accept = `${GITHUB_ENCODING__HTML_JSON},${GITHUB_ENCODING__REACTIONS_PREVIEW}`;
request.headers.set('Accept', accept);
return request;
}

export function loadCommentsPage(issueNumber: number, page: number): Promise<IssueComment[]> {
const request = commentsRequest(issueNumber, page);
export function loadCommentsPage(issueNumber: number, page: number, size: number): Promise<IssueComment[]> {
const request = commentsRequest(issueNumber, page, size);
return githubFetch(request).then(response => {
if (!response.ok) {
throw new Error('Error fetching comments.');
Expand Down
3 changes: 2 additions & 1 deletion src/page-attributes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ function readPageAttributes() {
title: params.title,
description: params.description,
label: params.label,
theme: params.theme || 'github-light'
theme: params.theme || 'github-light',
size: Math.round(Math.abs(+params.size)) || 25
};
}

Expand Down
27 changes: 15 additions & 12 deletions src/utterances.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
loadUser,
postComment,
createIssue,
PAGE_SIZE,
IssueComment
} from './github';
import { TimelineComponent } from './timeline-component';
Expand Down Expand Up @@ -97,40 +96,44 @@ async function renderComments(issue: Issue, timeline: TimelineComponent) {
}
};

const pageCount = Math.ceil(issue.comments / PAGE_SIZE);
const pageCount = Math.ceil(issue.comments / page.size);
// always load the first page.
const pageLoads = [loadCommentsPage(issue.number, 1)];
const pageLoads = [loadCommentsPage(issue.number, 1, page.size)];
// if there are multiple pages, load the last page.
if (pageCount > 1) {
pageLoads.push(loadCommentsPage(issue.number, pageCount));
pageLoads.push(loadCommentsPage(issue.number, pageCount, page.size));
}
// if the last page is small, load the penultimate page.
if (pageCount > 2 && issue.comments % PAGE_SIZE < 3) {
pageLoads.push(loadCommentsPage(issue.number, pageCount - 1));
if (pageCount > 2 && issue.comments % page.size !== 0 && issue.comments % page.size <= page.size / 2) {
pageLoads.push(loadCommentsPage(issue.number, pageCount - 1, page.size));
}
// await all loads to reduce jank.
const pages = await Promise.all(pageLoads);
for (const page of pages) {
renderPage(page);
}
// enable loading hidden pages.
let hiddenPageCount = pageCount - pageLoads.length;
let hiddenCommentsCount = (pageCount - pageLoads.length) * page.size;
let nextHiddenPage = 2;
let dynamicPageSize = page.size;
const renderLoader = (afterPage: IssueComment[]) => {
if (hiddenPageCount === 0) {
if (hiddenCommentsCount <= 0) {
return;
}
const load = async () => {
loader.setBusy();
const page = await loadCommentsPage(issue.number, nextHiddenPage);
const page = await loadCommentsPage(issue.number, nextHiddenPage, dynamicPageSize);
loader.remove();
renderPage(page);
hiddenPageCount--;
nextHiddenPage++;
hiddenCommentsCount -= dynamicPageSize;
// page number stays the same if page size growing exponentially, otherwise increase by 1
nextHiddenPage = (dynamicPageSize < 16) ? nextHiddenPage : nextHiddenPage + 1;
// maximum page size of 16
dynamicPageSize = (dynamicPageSize < 16) ? dynamicPageSize * 2 : dynamicPageSize;
renderLoader(page);
};
const afterComment = afterPage.pop()!;
const loader = timeline.insertPageLoader(afterComment, hiddenPageCount * PAGE_SIZE, load);
const loader = timeline.insertPageLoader(afterComment, hiddenCommentsCount, load);
};
renderLoader(pages[0]);
}
Expand Down