66import * as vscode from 'vscode' ;
77import { Project , ProjectContainer } from './project' ;
88import { OctokitProvider } from "./octokitProvider" ;
9+ import AbortController from "abort-controller" ;
910
1011interface RawNotebookCell {
1112 language : string ;
@@ -72,10 +73,18 @@ export class IssuesNotebookProvider implements vscode.NotebookProvider {
7273 } , 0 ) ;
7374 }
7475
75- async executeCell ( _document : vscode . NotebookDocument , cell : vscode . NotebookCell | undefined ) : Promise < void > {
76+ async executeCell ( document : vscode . NotebookDocument , cell : vscode . NotebookCell | undefined , token : vscode . CancellationToken ) : Promise < void > {
77+
7678 if ( ! cell ) {
79+ // run them all
80+ for ( let cell of document . cells ) {
81+ if ( cell . cellKind === vscode . CellKind . Code ) {
82+ await this . executeCell ( document , cell , token ) ;
83+ }
84+ }
7785 return ;
7886 }
87+
7988 const doc = await vscode . workspace . openTextDocument ( cell . uri ) ;
8089 const project = this . container . lookupProject ( doc . uri ) ;
8190 const allQueryData = project . queryData ( doc ) ;
@@ -85,79 +94,97 @@ export class IssuesNotebookProvider implements vscode.NotebookProvider {
8594 const query = project . getOrCreate ( doc ) ;
8695 project . symbols . update ( query ) ;
8796
97+ const now = Date . now ( ) ;
98+ let allItems : SearchIssuesAndPullRequestsResponseItemsItem [ ] = [ ] ;
99+
100+ // fetch
88101 try {
102+ const abortCtl = new AbortController ( ) ;
103+ token . onCancellationRequested ( _ => abortCtl . abort ( ) ) ;
89104
90- // fetch
91- let now = Date . now ( ) ;
92- let allItems : SearchIssuesAndPullRequestsResponseItemsItem [ ] = [ ] ;
93105 for ( let queryData of allQueryData ) {
94106 const octokit = await this . octokit . lib ( ) ;
95- const options = octokit . search . issuesAndPullRequests . endpoint . merge ( {
96- q : queryData . q ,
97- sort : queryData . sort ,
98- order : queryData . order ,
99- per_page : 100 ,
100- } ) ;
101- const items = await octokit . paginate < SearchIssuesAndPullRequestsResponseItemsItem > ( < any > options ) ;
102- allItems = allItems . concat ( items ) ;
103- }
104- let duration = Date . now ( ) - now ;
105107
106- // sort
107- const [ first ] = allQueryData ;
108- const comparator = allQueryData . length >= 2 && allQueryData . every ( item => item . sort === first . sort ) && cmp . byName . get ( first . sort ! ) ;
109- if ( comparator ) {
110- allItems . sort ( first . sort === 'asc' ? cmp . invert ( comparator ) : comparator ) ;
108+ let page = 0 ;
109+ let count = 0 ;
110+ while ( ! token . isCancellationRequested ) {
111+
112+ const respone = await octokit . search . issuesAndPullRequests ( {
113+ q : queryData . q ,
114+ sort : ( < any > queryData . sort ) ,
115+ order : queryData . order ,
116+ per_page : 100 ,
117+ page,
118+ request : { signal : abortCtl . signal }
119+ } ) ;
120+ count += respone . data . items . length ;
121+ allItems = allItems . concat ( < any > respone . data . items ) ;
122+ if ( count >= respone . data . total_count ) {
123+ break ;
124+ }
125+ page += 1 ;
126+ }
127+ }
128+ } catch ( err ) {
129+ if ( ! token . isCancellationRequested ) {
130+ cell . outputs = [ {
131+ outputKind : vscode . CellOutputKind . Text ,
132+ text : JSON . stringify ( err )
133+ } ] ;
111134 }
135+ return ;
136+ }
112137
113- // "render"
114- const seen = new Set < number > ( ) ;
115- let html = getHtmlStub ( ) ;
116- let md = '' ;
117- let count = 0 ;
118- for ( let item of allItems ) {
119- if ( seen . has ( item . id ) ) {
120- continue ;
121- }
122- seen . add ( item . id ) ;
138+ // sort
139+ const [ first ] = allQueryData ;
140+ const comparator = allQueryData . length >= 2 && allQueryData . every ( item => item . sort === first . sort ) && cmp . byName . get ( first . sort ! ) ;
141+ if ( comparator ) {
142+ allItems . sort ( first . sort === 'asc' ? cmp . invert ( comparator ) : comparator ) ;
143+ }
123144
124- // markdown
125- md += `- [#${ item . number } ](${ item . html_url } ) ${ item . title } [${ item . labels . map ( label => `${ label . name } ` ) . join ( ', ' ) } ]` ;
126- if ( item . assignee ) {
127- md += `- [@${ item . assignee . login } ](${ item . assignee . html_url } )\n` ;
128- }
129- md += '\n' ;
145+ // "render"
146+ const duration = Date . now ( ) - now ;
147+ const seen = new Set < number > ( ) ;
148+ let html = getHtmlStub ( ) ;
149+ let md = '' ;
150+ let count = 0 ;
151+ for ( let item of allItems ) {
152+ if ( seen . has ( item . id ) ) {
153+ continue ;
154+ }
155+ seen . add ( item . id ) ;
130156
131- // html
132- html += renderItemAsHtml ( item , count ++ > 12 ) ;
157+ // markdown
158+ md += `- [#${ item . number } ](${ item . html_url } ) ${ item . title } [${ item . labels . map ( label => `${ label . name } ` ) . join ( ', ' ) } ]` ;
159+ if ( item . assignee ) {
160+ md += `- [@${ item . assignee . login } ](${ item . assignee . html_url } )\n` ;
133161 }
162+ md += '\n' ;
163+
164+ // html
165+ html += renderItemAsHtml ( item , count ++ > 12 ) ;
166+ }
134167
135- //collapse/expand btns
136- html += `<div class="collapse"><script>function toggle(element, more) { element.parentNode.parentNode.classList.toggle("collapsed", !more)}</script><span class="more" onclick="toggle(this, true)">▼ Show More</span><span class="less" onclick="toggle(this, false)">▲ Show Less</span></div>` ;
168+ //collapse/expand btns
169+ html += `<div class="collapse"><script>function toggle(element, more) { element.parentNode.parentNode.classList.toggle("collapsed", !more)}</script><span class="more" onclick="toggle(this, true)">▼ Show More</span><span class="less" onclick="toggle(this, false)">▲ Show Less</span></div>` ;
137170
138- // status line
139- html += `<div class="stats" data-ts=${ now } >${ allItems . length } results, queried {{NOW}}, took ${ ( duration / 1000 ) . toPrecision ( 2 ) } secs</div>` ;
140- html += `<script>
171+ // status line
172+ html += `<div class="stats" data-ts=${ now } >${ allItems . length } results, queried {{NOW}}, took ${ ( duration / 1000 ) . toPrecision ( 2 ) } secs</div>` ;
173+ html += `<script>
141174 var node = document.currentScript.parentElement.querySelector(".stats");
142175 node.innerText = node.innerText.replace("{{NOW}}", new Date(Number(node.dataset['ts'])).toLocaleString());
143176 </script>` ;
144177
145- cell . outputs = [ {
146- outputKind : vscode . CellOutputKind . Rich ,
147- data : {
148- [ 'text/html' ] : `<div class="${ count > 12 ? 'large collapsed' : '' } ">${ html } </div>` ,
149- [ 'text/markdown' ] : md ,
150- [ 'text/plain' ] : allQueryData . map ( d => `${ d . q } , ${ d . sort || 'default' } sort` ) . join ( '\n\n' )
151- }
152- } ] ;
178+ cell . outputs = [ {
179+ outputKind : vscode . CellOutputKind . Rich ,
180+ data : {
181+ [ 'text/html' ] : `<div class="${ count > 12 ? 'large collapsed' : '' } ">${ html } </div>` ,
182+ [ 'text/markdown' ] : md ,
183+ [ 'text/plain' ] : allQueryData . map ( d => `${ d . q } , ${ d . sort || 'default' } sort` ) . join ( '\n\n' )
184+ }
185+ } ] ;
186+
153187
154- } catch ( err ) {
155- console . error ( err ) ;
156- cell . outputs = [ {
157- outputKind : vscode . CellOutputKind . Text ,
158- text : JSON . stringify ( err )
159- } ] ;
160- }
161188 }
162189
163190 async save ( document : vscode . NotebookDocument ) : Promise < boolean > {
0 commit comments