diff --git a/src/configuration-component.ts b/src/configuration-component.ts index 542421ca..3100beb4 100644 --- a/src/configuration-component.ts +++ b/src/configuration-component.ts @@ -146,6 +146,11 @@ export class ConfigurationComponent {

+ +

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



`; diff --git a/src/github.ts b/src/github.ts index 61f5d2ad..3ddded45 100644 --- a/src/github.ts +++ b/src/github.ts @@ -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']; @@ -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 { - const request = commentsRequest(issueNumber, page); +export function loadCommentsPage(issueNumber: number, page: number, size: number): Promise { + const request = commentsRequest(issueNumber, page, size); return githubFetch(request).then(response => { if (!response.ok) { throw new Error('Error fetching comments.'); diff --git a/src/page-attributes.ts b/src/page-attributes.ts index 3823b40c..d5574f9d 100644 --- a/src/page-attributes.ts +++ b/src/page-attributes.ts @@ -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 }; } diff --git a/src/utterances.ts b/src/utterances.ts index 0967b152..b4025a65 100644 --- a/src/utterances.ts +++ b/src/utterances.ts @@ -8,7 +8,6 @@ import { loadUser, postComment, createIssue, - PAGE_SIZE, IssueComment } from './github'; import { TimelineComponent } from './timeline-component'; @@ -97,16 +96,16 @@ 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); @@ -114,23 +113,27 @@ async function renderComments(issue: Issue, timeline: TimelineComponent) { 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]); }