1+ /*global Clipboard, moment, numeral, Shuffle, Chart*/
2+
3+ import { StatsModal } from "../modal.js" ;
4+ import { getUrl , ajax } from "../utils.js" ;
5+
6+ // todo, most of this to be moved to start.js class
7+
8+ function onLoad ( ) {
9+
10+ ////////////////////////////
11+ // stats modal handling
12+
13+ StatsModal . init ( ) ;
14+
15+ /////////////////////////
16+ // other logic
17+
18+ function formatDate ( date ) {
19+ return moment ( date ) . format ( "YYYY/MM/DD" ) ;
20+ }
21+
22+ function parse ( json ) {
23+ let repos = [ ] ;
24+ for ( let name in json ) {
25+ repos . push ( {
26+ name : json [ name ] . repo . name ,
27+ description : json [ name ] . repo . description ,
28+ git_url : json [ name ] . repo . clone_url ,
29+ stars : json [ name ] . repo . stargazers_count ,
30+ html_url : json [ name ] . repo . html_url ,
31+ owner : json [ name ] . repo . owner . login ,
32+ owner_url : json [ name ] . repo . owner . html_url ,
33+ lines : json [ name ] . lines ,
34+ cloud : json [ name ] . parsing . cloud ,
35+ license : json [ name ] . repo . license ? json [ name ] . repo . license . name : "null" ,
36+ created_at : new Date ( json [ name ] . repo . created_at ) ,
37+ pushed_at : new Date ( json [ name ] . repo . pushed_at )
38+ } ) ;
39+ }
40+ return { repos } ;
41+ }
42+
43+ function render ( { repos } ) {
44+ let html = "" ;
45+ for ( let i = 0 ; i < repos . length ; ++ i ) {
46+ let repo = repos [ i ] ;
47+
48+ let cloud = `` ;
49+ if ( repo . cloud === 0 ) {
50+ cloud = `<div class="level-item" title="cloud ready, only syntax, disregarding whitelist">
51+ <span class="icon is-small"><i class="fa fa-cloud"></i></span>
52+ </div>` ;
53+ }
54+
55+ html += `<div class="column is-half-tablet is-one-third-desktop" data-index="${ i } ">
56+ <div class="box">
57+ <article class="media">
58+ <figure class="media-left">
59+ <p class="image is-64x64">
60+ <img src="${ repo . owner_url } .png?size=64">
61+ </p>
62+ </figure>
63+ <div class="media-content">
64+ <div class="content">
65+ <p>
66+ <a href="${ repo . html_url } "><strong class="huge">${ repo . name } </strong></a>
67+ <small><em>
68+ created by
69+ <a href="${ repo . owner_url } ">${ repo . owner } </a>
70+ <span title="${ formatDate ( repo . created_at ) } ">
71+ ${ moment ( repo . created_at ) . fromNow ( ) }
72+ </span>
73+ </em></small><br>
74+ ${ repo . description } <br>
75+ <em>${ repo . license } </em>
76+ </p>
77+ </div>
78+ </div>
79+ </article>
80+ <div class="field has-addons has-small-top-margin">
81+ <p class="control">
82+ <a class="button is-static">
83+ Git
84+ </a>
85+ </p>
86+ <p class="control is-expanded">
87+ <input class="input" type="text" value="${ repo . git_url } " readonly>
88+ </p>
89+ <p class="control" title="copy to clipboard">
90+ <a class="button is-clipboard-enabled" data-clipboard-text="${ repo . git_url } ">
91+ <span class="icon"><i class="fa fa-clipboard"></i></span>
92+ </a>
93+ </p>
94+ </div>
95+ <nav class="level is-mobile">
96+ <div class="level-left">
97+ <div class="level-item" title="stars">
98+ <span class="icon is-small"><i class="fa fa-star"></i></span> ${ repo . stars }
99+ </div>
100+ <div class="level-item" title="lines of code">
101+ <span class="icon is-small"><i class="fa fa-code"></i></span> ${ numeral ( repo . lines ) . format ( "0.[0]a" ) }
102+ </div>
103+ <div class="level-item" title="last updated at">
104+ <span class="icon is-small"><i class="fa fa-pencil"></i></span> ${ formatDate ( repo . pushed_at ) }
105+ </div>
106+ ${ cloud }
107+ <div class="level-item" title="stats">
108+ <span class="icon is-small"><img onclick="javascript:stats('${ repo . owner } ','${ repo . name } ');" src="./logos/abaplint.svg"></span>
109+ </div>
110+ </div>
111+ </nav>
112+ </div>
113+ </div>` ;
114+ }
115+ document . getElementById ( "list" ) . innerHTML = html ;
116+ document . getElementById ( "burger" ) . classList . remove ( "is-active" ) ;
117+ document . getElementById ( "menu" ) . classList . remove ( "is-active" ) ;
118+ return repos ;
119+ }
120+
121+ function hideMenu ( ) {
122+ document . getElementById ( "burger" ) . classList . remove ( "is-active" ) ;
123+ document . getElementById ( "menu" ) . classList . remove ( "is-active" ) ;
124+ return false ;
125+ }
126+
127+ function toggleMenu ( ) {
128+ document . getElementById ( "burger" ) . classList . toggle ( "is-active" ) ;
129+ document . getElementById ( "menu" ) . classList . toggle ( "is-active" ) ;
130+ return false ;
131+ }
132+
133+ function afterRender ( repos ) {
134+ var shuffle = null ;
135+ let cloud_filter = false ;
136+
137+ function sort ( attribute , descending ) {
138+ shuffle . sort ( {
139+ reverse : descending ,
140+ by : element => {
141+ let v = repos [ element . getAttribute ( "data-index" ) ] [ attribute ] ;
142+ return typeof v === "string" ? v . toLowerCase ( ) : v
143+ }
144+ } ) ;
145+ hideMenu ( ) ;
146+ return false ;
147+ }
148+
149+ let search = ( function ( ) {
150+ let inner = ( ) => {
151+ let query = document . getElementById ( "search" ) . value ;
152+ let regex = new RegExp ( query , 'i' ) ;
153+ let predicate = repo => ( ! cloud_filter || repo . cloud === 0 ) &&
154+ ( repo . description . match ( regex ) || repo . owner . match ( regex ) || repo . name . match ( regex ) ) ;
155+ shuffle . filter ( element => predicate ( repos [ element . getAttribute ( "data-index" ) ] ) ) ;
156+ }
157+ let timeout = null ;
158+ let later = ( ) => {
159+ timeout = null ;
160+ inner ( ) ;
161+ } ;
162+ return ( ) => {
163+ if ( timeout ) {
164+ clearTimeout ( timeout ) ;
165+ }
166+ timeout = setTimeout ( later , 500 ) ;
167+ }
168+ } ) ( ) ;
169+
170+ function rightClick ( ) {
171+ document . getElementById ( "search" ) . value = "" ;
172+ window . event . returnValue = false ;
173+ search ( ) ;
174+ }
175+
176+ function filter ( attribute ) {
177+ cloud_filter = ! cloud_filter ;
178+ search ( ) ;
179+ hideMenu ( ) ;
180+ return false ;
181+ }
182+
183+ new Clipboard ( ".is-clipboard-enabled" ) ;
184+ shuffle = new Shuffle ( document . getElementById ( "list" ) , { itemSelector : ".column" , delimiter : "," } ) ;
185+
186+ sort ( "pushed_at" , true ) ;
187+
188+ setTimeout ( ( ) => {
189+ document . getElementById ( "main" ) . classList . toggle ( "is-hidden" ) ;
190+ document . getElementById ( "loading" ) . classList . toggle ( "is-hidden" ) ;
191+ document . getElementById ( "nav" ) . classList . toggle ( "is-hidden" ) ;
192+ document . getElementById ( "footer" ) . classList . toggle ( "is-hidden" ) ;
193+ document . getElementById ( "search" ) . onkeyup = search ;
194+ document . getElementById ( "search" ) . oncontextmenu = rightClick ;
195+ document . getElementById ( "burger" ) . onclick = toggleMenu ;
196+ document . getElementById ( "search-button" ) . onclick = search ;
197+ document . getElementById ( "sort-by-name" ) . onclick = sort . bind ( null , "name" , false ) ;
198+ document . getElementById ( "sort-by-stars" ) . onclick = sort . bind ( null , "stars" , true ) ;
199+ document . getElementById ( "sort-by-updated" ) . onclick = sort . bind ( null , "pushed_at" , true ) ;
200+ document . getElementById ( "sort-by-size" ) . onclick = sort . bind ( null , "lines" , true ) ;
201+ document . getElementById ( "sort-by-created" ) . onclick = sort . bind ( null , "created_at" , true ) ;
202+ document . getElementById ( "sort-by-author" ) . onclick = sort . bind ( null , "owner" , false ) ;
203+ document . getElementById ( "filter-by-cloud" ) . onclick = filter . bind ( null , "cloud" ) ;
204+ shuffle . update ( ) ;
205+ } , 500 ) ;
206+
207+ shuffle . on ( Shuffle . EventType . LAYOUT , function ( ) {
208+ let projects = 0 ;
209+ let total = 0 ;
210+ for ( let item of shuffle . items ) {
211+ if ( item . isVisible === true ) {
212+ projects = projects + 1 ;
213+ total = total + repos [ item . id - 1 ] . lines ;
214+ }
215+ }
216+ document . getElementById ( "loc_count" ) . innerHTML = numeral ( total ) . format ( "0.[0]a" ) ;
217+ document . getElementById ( "project_count" ) . innerHTML = numeral ( projects ) . format ( "0.[0]a" ) ;
218+ } ) ;
219+ }
220+
221+ ajax ( getUrl ( ) )
222+ . then ( parse )
223+ . then ( render )
224+ . then ( afterRender )
225+ . catch ( ( e ) => { console . log ( "Error loading" ) ; console . dir ( e ) ; } ) ;
226+ }
227+
228+
1229export class Start {
2230 static render ( ) {
3231 document . getElementById ( "main" ) . innerHTML = `
@@ -124,5 +352,7 @@ export class Start {
124352 </div>
125353 </div>
126354 ` ;
355+
356+ onLoad ( ) ;
127357 }
128358}
0 commit comments