@@ -7,8 +7,7 @@ const state = {
77 currentView : 'loading' ,
88 currentPath : [ ] ,
99 currentItem : null ,
10- isLoading : true ,
11- isInitialized : false
10+ isLoading : true
1211} ;
1312
1413// Utility
@@ -17,20 +16,18 @@ function getRepoPath() {
1716 return parts [ 1 ] && parts [ 2 ] ? `${ parts [ 1 ] } /${ parts [ 2 ] } ` : 'Vic-Nas/PythonSolutions' ;
1817}
1918
20- // Fetch folder contents with cache busting and validation
19+ // Fetch folder contents with better caching
2120async function fetchFolderContents ( path ) {
2221 const cacheKey = path ;
2322 const cached = state . folderCache [ cacheKey ] ;
2423
25- // Cache for 5 minutes
26- if ( cached && Date . now ( ) - cached . timestamp < 300000 ) {
24+ // Cache for 2 minutes
25+ if ( cached && cached . data && Date . now ( ) - cached . timestamp < 120000 ) {
2726 return cached . data ;
2827 }
2928
3029 try {
31- const res = await fetch ( `https://api.github.com/repos/${ getRepoPath ( ) } /contents/${ path } ` , {
32- cache : 'no-cache' // Force fresh data from GitHub
33- } ) ;
30+ const res = await fetch ( `https://api.github.com/repos/${ getRepoPath ( ) } /contents/${ path } ` ) ;
3431 if ( ! res . ok ) return null ;
3532
3633 const items = await res . json ( ) ;
@@ -55,79 +52,69 @@ function hasFiles(items) {
5552 ) ;
5653}
5754
58- // Load all platforms with proper error handling
55+ // Load all platforms
5956async function loadPlatforms ( ) {
6057 console . log ( 'Loading platforms...' ) ;
58+ const rootItems = await fetchFolderContents ( '' ) ;
59+ if ( ! rootItems ) {
60+ console . error ( 'Failed to load root items' ) ;
61+ return ;
62+ }
6163
62- try {
63- const rootItems = await fetchFolderContents ( '' ) ;
64- if ( ! rootItems ) {
65- console . error ( 'Failed to load root items' ) ;
66- return ;
67- }
68-
69- const platformFolders = rootItems . filter ( item =>
70- item . type === 'dir' &&
71- ! [ 'utils' , '.git' ] . includes ( item . name ) &&
72- ! item . name . startsWith ( '.' )
73- ) ;
74-
75- // Load platforms sequentially to avoid race conditions
76- const platforms = [ ] ;
64+ const platformFolders = rootItems . filter ( item =>
65+ item . type === 'dir' &&
66+ ! [ 'utils' , '.git' ] . includes ( item . name ) &&
67+ ! item . name . startsWith ( '.' )
68+ ) ;
69+
70+ // Build all platforms first
71+ const platforms = [ ] ;
72+
73+ for ( const folder of platformFolders ) {
74+ const platformData = {
75+ name : folder . name ,
76+ path : folder . name ,
77+ image : null ,
78+ count : 0
79+ } ;
7780
78- for ( const folder of platformFolders ) {
79- const platformData = {
80- name : folder . name ,
81- path : folder . name ,
82- image : null ,
83- count : 0
84- } ;
85-
86- // Check for platform.png
87- const contents = await fetchFolderContents ( folder . name ) ;
88- if ( contents ) {
89- const platformImg = contents . find ( f => f . name === 'platform.png' ) ;
90- if ( platformImg ) {
91- platformData . image = platformImg . download_url || `${ folder . name } /platform.png` ;
92- }
93-
94- // Count items recursively
95- platformData . count = await countItems ( folder . name ) ;
81+ // Check for platform.png
82+ const contents = await fetchFolderContents ( folder . name ) ;
83+ if ( contents ) {
84+ const platformImg = contents . find ( f => f . name === 'platform.png' ) ;
85+ if ( platformImg ) {
86+ // Use the download_url from GitHub API
87+ platformData . image = platformImg . download_url || `${ folder . name } /platform.png` ;
9688 }
9789
98- platforms . push ( platformData ) ;
90+ // Count items recursively
91+ platformData . count = await countItems ( folder . name ) ;
9992 }
10093
101- // Sort and assign only after all data is loaded
102- platforms . sort ( ( a , b ) => a . name . localeCompare ( b . name ) ) ;
103- state . platforms = platforms ;
104-
105- console . log ( 'Loaded platforms:' , state . platforms ) ;
106- } catch ( err ) {
107- console . error ( 'Error loading platforms:' , err ) ;
94+ platforms . push ( platformData ) ;
10895 }
96+
97+ platforms . sort ( ( a , b ) => a . name . localeCompare ( b . name ) ) ;
98+ state . platforms = platforms ;
99+
100+ console . log ( 'Loaded platforms:' , state . platforms ) ;
109101}
110102
111103// Recursively count problem items
112104async function countItems ( path ) {
113- try {
114- const items = await fetchFolderContents ( path ) ;
115- if ( ! items ) return 0 ;
116-
117- if ( hasFiles ( items ) ) return 1 ;
118-
119- const subdirs = items . filter ( i => i . type === 'dir' ) ;
120- let count = 0 ;
121-
122- for ( const dir of subdirs ) {
123- count += await countItems ( `${ path } /${ dir . name } ` ) ;
124- }
125-
126- return count ;
127- } catch ( err ) {
128- console . error ( `Error counting items in ${ path } :` , err ) ;
129- return 0 ;
105+ const items = await fetchFolderContents ( path ) ;
106+ if ( ! items ) return 0 ;
107+
108+ if ( hasFiles ( items ) ) return 1 ;
109+
110+ const subdirs = items . filter ( i => i . type === 'dir' ) ;
111+ let count = 0 ;
112+
113+ for ( const dir of subdirs ) {
114+ count += await countItems ( `${ path } /${ dir . name } ` ) ;
130115 }
116+
117+ return count ;
131118}
132119
133120// Parse hash to navigate
@@ -158,14 +145,10 @@ function render() {
158145 console . log ( 'Rendering view:' , state . currentView , 'path:' , state . currentPath ) ;
159146
160147 const views = [ 'loading-screen' , 'platform-selector' , 'folder-view' , 'problem-view' ] ;
161- views . forEach ( v => {
162- const el = document . getElementById ( v ) ;
163- if ( el ) el . style . display = 'none' ;
164- } ) ;
148+ views . forEach ( v => document . getElementById ( v ) . style . display = 'none' ) ;
165149
166150 if ( state . currentView === 'loading' ) {
167- const el = document . getElementById ( 'loading-screen' ) ;
168- if ( el ) el . style . display = 'flex' ;
151+ document . getElementById ( 'loading-screen' ) . style . display = 'flex' ;
169152 } else if ( state . currentView === 'platforms' ) {
170153 renderPlatforms ( ) ;
171154 } else if ( state . currentView === 'folder' ) {
@@ -176,19 +159,10 @@ function render() {
176159}
177160
178161function renderPlatforms ( ) {
179- const selector = document . getElementById ( 'platform-selector' ) ;
162+ document . getElementById ( 'platform-selector' ) . style . display = 'block' ;
180163 const grid = document . getElementById ( 'platform-grid' ) ;
181-
182- if ( ! selector || ! grid ) return ;
183-
184- selector . style . display = 'block' ;
185164 grid . innerHTML = '' ;
186165
187- if ( state . platforms . length === 0 ) {
188- grid . innerHTML = '<p style="grid-column: 1/-1; text-align: center;">No platforms found</p>' ;
189- return ;
190- }
191-
192166 state . platforms . forEach ( platform => {
193167 const card = document . createElement ( 'button' ) ;
194168 card . className = 'platform-box' ;
@@ -213,8 +187,6 @@ function renderPlatforms() {
213187
214188async function renderFolder ( ) {
215189 const view = document . getElementById ( 'folder-view' ) ;
216- if ( ! view ) return ;
217-
218190 view . style . display = 'block' ;
219191
220192 const pathStr = state . currentPath . join ( '/' ) ;
@@ -230,17 +202,14 @@ async function renderFolder() {
230202
231203 // Set title
232204 const titleParts = state . currentPath . map ( capitalize ) ;
233- const titleEl = document . getElementById ( 'folder-title' ) ;
234- if ( titleEl ) titleEl . textContent = titleParts . join ( ' / ' ) ;
205+ document . getElementById ( 'folder-title' ) . textContent = titleParts . join ( ' / ' ) ;
235206
236207 // Setup back button
237208 const backBtn = document . getElementById ( 'back-button' ) ;
238- if ( backBtn ) backBtn . onclick = goBack ;
209+ backBtn . onclick = goBack ;
239210
240211 // Render cards
241212 const container = document . getElementById ( 'folder-cards' ) ;
242- if ( ! container ) return ;
243-
244213 container . innerHTML = '' ;
245214
246215 for ( const dir of subdirs ) {
@@ -263,8 +232,6 @@ async function renderFolder() {
263232
264233async function renderProblem ( ) {
265234 const view = document . getElementById ( 'problem-view' ) ;
266- if ( ! view ) return ;
267-
268235 view . style . display = 'block' ;
269236 view . innerHTML = '<div style="text-align: center; padding: 3rem;">Loading...</div>' ;
270237
@@ -304,9 +271,7 @@ async function renderProblem() {
304271
305272 if ( pyFiles . length > 0 ) {
306273 try {
307- const res = await fetch ( `https://api.github.com/repos/${ getRepoPath ( ) } /contents/${ pathStr } /${ pyFiles [ 0 ] . name } ` , {
308- cache : 'no-cache'
309- } ) ;
274+ const res = await fetch ( `https://api.github.com/repos/${ getRepoPath ( ) } /contents/${ pathStr } /${ pyFiles [ 0 ] . name } ` ) ;
310275 if ( res . ok ) {
311276 const data = await res . json ( ) ;
312277 pythonCode = atob ( data . content ) ;
@@ -403,8 +368,6 @@ async function renderProblem() {
403368 }
404369
405370 view . innerHTML = html ;
406-
407- // Highlight code if hljs is available
408371 if ( typeof hljs !== 'undefined' ) {
409372 hljs . highlightAll ( ) ;
410373 }
@@ -436,18 +399,22 @@ function goBack() {
436399 // If we're viewing a problem, go back to its parent folder
437400 if ( state . currentView === 'problem' ) {
438401 if ( state . currentPath . length > 1 ) {
402+ // Go to parent folder
439403 const parentPath = state . currentPath . slice ( 0 , - 1 ) ;
440404 window . location . hash = parentPath . map ( encodeURIComponent ) . join ( '/' ) ;
441405 } else {
406+ // Go to home
442407 window . location . hash = '' ;
443408 }
444409 }
445410 // If we're in a folder view, go back one level
446411 else if ( state . currentView === 'folder' ) {
447412 if ( state . currentPath . length > 1 ) {
413+ // Go to parent folder
448414 const parentPath = state . currentPath . slice ( 0 , - 1 ) ;
449415 window . location . hash = parentPath . map ( encodeURIComponent ) . join ( '/' ) ;
450416 } else {
417+ // Go to home
451418 window . location . hash = '' ;
452419 }
453420 }
@@ -480,12 +447,6 @@ function getDefaultEmoji(platformName) {
480447
481448// Event listeners
482449window . addEventListener ( 'hashchange' , async ( ) => {
483- // Ignore hash changes during initial load
484- if ( state . isLoading ) {
485- console . log ( 'Ignoring hash change during initial load' ) ;
486- return ;
487- }
488-
489450 console . log ( 'Hash changed' ) ;
490451 const parsed = parseHash ( ) ;
491452 state . currentView = parsed . view ;
@@ -506,27 +467,19 @@ window.addEventListener('hashchange', async () => {
506467 return ;
507468 }
508469
509- // Set loading state
510- state . isLoading = true ;
511- state . currentView = 'loading' ;
512- render ( ) ;
470+ // Make goBack globally available for onclick handler
471+ window . goBack = goBack ;
513472
514- // Load platforms completely before proceeding
473+ // Load platforms
515474 await loadPlatforms ( ) ;
516475
517- // Mark as initialized
518- state . isLoading = false ;
519- state . isInitialized = true ;
520-
521- // Now parse hash and render
476+ // Parse initial hash and render
522477 const parsed = parseHash ( ) ;
523478 state . currentView = parsed . view ;
524479 state . currentPath = parsed . path ;
480+ state . isLoading = false ;
525481
526482 console . log ( 'Initial state:' , state ) ;
527483
528- // Make goBack globally available for onclick handler
529- window . goBack = goBack ;
530-
531484 render ( ) ;
532485} ) ( ) ;
0 commit comments