@@ -15,43 +15,92 @@ document.addEventListener('DOMContentLoaded', async () => {
1515 let devices , imagesData ;
1616
1717 if ( cachedData ) {
18+ console . log ( 'Using cached device data' ) ;
1819 ( { devices, imagesData } = cachedData ) ;
1920 } else {
20- const [ devicesRes , imagesRes ] = await Promise . all ( [
21- fetch ( 'https://raw.githubusercontent.com/AxionAOSP/official_devices/refs/heads/main/README.md' ) ,
22- fetch ( 'https://raw.githubusercontent.com/AxionAOSP/official_devices/refs/heads/main/OTA/device_images.json' )
23- ] ) ;
21+ console . log ( 'Fetching fresh device data...' ) ;
22+ try {
23+ const [ devicesRes , imagesRes ] = await Promise . all ( [
24+ fetch ( 'https://raw.githubusercontent.com/AxionAOSP/official_devices/main/README.md' ) ,
25+ fetch ( 'https://raw.githubusercontent.com/AxionAOSP/official_devices/main/OTA/device_images.json' )
26+ ] ) ;
27+
28+ if ( ! devicesRes . ok ) {
29+ throw new Error ( `Failed to fetch devices: ${ devicesRes . status } ${ devicesRes . statusText } ` ) ;
30+ }
2431
25- const [ devicesText , images ] = await Promise . all ( [
26- devicesRes . text ( ) ,
27- imagesRes . json ( )
28- ] ) ;
32+ if ( ! imagesRes . ok ) {
33+ throw new Error ( `Failed to fetch images: ${ imagesRes . status } ${ imagesRes . statusText } ` ) ;
34+ }
35+
36+ const [ devicesText , images ] = await Promise . all ( [
37+ devicesRes . text ( ) ,
38+ imagesRes . json ( )
39+ ] ) ;
2940
30- devices = processDevices ( devicesText ) ;
31- imagesData = images ;
32- saveToCache ( 'device_data' , { devices, imagesData } ) ;
41+ console . log ( 'Data fetched successfully, processing...' ) ;
42+ devices = processDevices ( devicesText ) ;
43+
44+ if ( ! devices || devices . length === 0 ) {
45+ throw new Error ( 'No devices found after processing README' ) ;
46+ }
47+
48+ console . log ( `Processed ${ devices . length } devices successfully` ) ;
49+ imagesData = images ;
50+ saveToCache ( 'device_data' , { devices, imagesData } ) ;
51+ } catch ( fetchError ) {
52+ console . error ( 'Fetch error:' , fetchError ) ;
53+ throw fetchError ; // Re-throw to be caught by outer try-catch
54+ }
3355 }
3456
3557 const deviceElements = await createDeviceElements ( devices , imagesData ) ;
58+ console . log ( `Created ${ deviceElements . length } device elements` ) ;
59+
3660 deviceElements . forEach ( element => {
3761 element . style . display = 'none' ;
3862 grid . appendChild ( element ) ;
3963 } ) ;
4064
65+ // Show the first brand by default
66+ const allBrands = [ ...new Set ( devices . map ( d => d . brand ) ) ] ;
67+ if ( allBrands . length > 0 ) {
68+ const defaultBrand = allBrands [ 0 ] ;
69+ document . querySelectorAll ( '.device-card' ) . forEach ( card => {
70+ card . style . display = card . dataset . brand === defaultBrand ? 'block' : 'none' ;
71+ } ) ;
72+
73+ // Highlight the default brand button if exists
74+ const defaultButton = document . querySelector ( `.filter-btn[data-filter="${ defaultBrand } "]` ) ;
75+ if ( defaultButton ) {
76+ defaultButton . classList . add ( 'active' ) ;
77+ }
78+ }
79+
4180 initFilters ( ) ;
4281 initSearch ( ) ;
4382 initModalLogic ( ) ;
4483
4584 } catch ( error ) {
46- console . error ( 'Error:' , error ) ;
85+ console . error ( 'Error loading devices :' , error ) ;
4786 grid . innerHTML = `
4887 <div class="error">
4988 <i class="fas fa-exclamation-triangle"></i>
5089 <p>Failed to load devices. Please check the
5190 <a href="https://github.com/AxionAOSP/official_devices" target="_blank">official repository</a>.
5291 </p>
92+ <button id="retryBtn" class="retry-button">
93+ <i class="fas fa-sync"></i> Retry
94+ </button>
5395 </div>
5496 ` ;
97+
98+ // Add retry functionality
99+ document . getElementById ( 'retryBtn' ) ?. addEventListener ( 'click' , ( ) => {
100+ // Clear cache and reload
101+ localStorage . removeItem ( 'device_data' ) ;
102+ window . location . reload ( ) ;
103+ } ) ;
55104 } finally {
56105 loading . style . display = 'none' ;
57106 }
@@ -136,49 +185,78 @@ function processDevices(text) {
136185 const startIndex = text . indexOf ( startMarker ) ;
137186 const endIndex = text . indexOf ( endMarker ) ;
138187
139- if ( startIndex === - 1 || endIndex === - 1 ) {
140- console . error ( 'Device table markers not found in README. Start:' , startIndex , 'End:' , endIndex ) ;
188+ if ( startIndex === - 1 ) {
189+ console . error ( 'Device section start marker not found in README' ) ;
141190 return [ ] ;
142191 }
143-
144- const tableSection = text . slice ( startIndex , endIndex ) . trim ( ) ;
145192
146- // Get table rows - skip header and separator rows
193+ if ( endIndex === - 1 ) {
194+ console . error ( 'Device section end marker not found in README' ) ;
195+ // Try to process just using the start marker if end marker is missing
196+ const sectionText = text . slice ( startIndex ) ;
197+ console . log ( 'Attempting to process without end marker. Text sample:' ,
198+ sectionText . substring ( 0 , 200 ) + '...' ) ;
199+ }
200+
201+ // If endIndex is -1, this will go to the end of the text, which is fine as a fallback
202+ const tableSection = text . slice ( startIndex , endIndex !== - 1 ? endIndex : undefined ) . trim ( ) ;
203+
204+ console . log ( 'Table section extracted. Sample:' , tableSection . substring ( 0 , 200 ) + '...' ) ;
205+
206+ // Get table rows - look for pipe character at start
147207 const rows = tableSection
148208 . split ( '\n' )
149- . filter ( line => line . trim ( ) . startsWith ( '|' ) && ! line . includes ( '---' ) ) ;
209+ . filter ( line => line . trim ( ) . startsWith ( '|' ) ) ;
210+
211+ console . log ( `Found ${ rows . length } total rows in table` ) ;
150212
151- // Skip the header row
213+ // Need at least header + separator + 1 data row
214+ if ( rows . length < 3 ) {
215+ console . error ( 'Not enough rows found in device table' ) ;
216+ return [ ] ;
217+ }
218+
219+ // Skip header and separator rows
152220 const dataRows = rows . slice ( 2 ) ;
153221
154- console . log ( `Found ${ dataRows . length } device entries in README ` ) ;
222+ console . log ( `Processing ${ dataRows . length } device entries` ) ;
155223
156- return dataRows
157- . map ( line => {
158- // Split by pipe and clean up cells
159- const columns = line . split ( '|' ) . map ( col => col . trim ( ) ) . filter ( Boolean ) ;
160-
161- if ( columns . length < 2 ) {
162- console . warn ( 'Invalid row format:' , line ) ;
224+ const devices = dataRows
225+ . map ( ( line , index ) => {
226+ try {
227+ // Split by pipe and clean up cells
228+ const columns = line . split ( '|' )
229+ . map ( col => col . trim ( ) )
230+ . filter ( Boolean ) ;
231+
232+ if ( columns . length < 2 ) {
233+ console . warn ( `Row ${ index } has insufficient columns:` , line ) ;
234+ return null ;
235+ }
236+
237+ // Extract device name and codename
238+ const name = columns [ 0 ] . replace ( / \* \* / g, '' ) . trim ( ) ;
239+ const codename = columns [ 1 ] . replace ( / ` / g, '' ) . trim ( ) ;
240+
241+ if ( ! name || ! codename ) {
242+ console . warn ( `Row ${ index } is missing name or codename:` , { name, codename, line } ) ;
243+ return null ;
244+ }
245+
246+ return {
247+ name,
248+ codename,
249+ brand : getDeviceBrand ( name ) ,
250+ } ;
251+ } catch ( rowError ) {
252+ console . error ( `Error processing row ${ index } :` , rowError , line ) ;
163253 return null ;
164254 }
165-
166- // Extract device name and codename
167- const name = columns [ 0 ] . replace ( / \* \* / g, '' ) . trim ( ) ;
168- const codename = columns [ 1 ] . replace ( / ` / g, '' ) . trim ( ) ;
169-
170- if ( ! name || ! codename ) {
171- console . warn ( 'Missing data in row:' , line ) ;
172- return null ;
173- }
174-
175- return {
176- name,
177- codename,
178- brand : getDeviceBrand ( name ) ,
179- } ;
180255 } )
181256 . filter ( Boolean ) ;
257+
258+ console . log ( `Successfully processed ${ devices . length } devices` ) ;
259+ return devices ;
182260 } catch ( error ) {
183261 console . error ( 'Error processing devices:' , error , error . stack ) ;
184262 return [ ] ;
@@ -422,4 +500,24 @@ function getDeviceBrand(deviceName) {
422500
423501 brandCache . set ( deviceName , brand ) ;
424502 return brand ;
425- }
503+ }
504+
505+ // Add the retry button styling
506+ document . head . insertAdjacentHTML ( 'beforeend' , `
507+ <style>
508+ .retry-button {
509+ margin-top: 15px;
510+ padding: 8px 16px;
511+ background: #2196F3;
512+ color: white;
513+ border: none;
514+ border-radius: 4px;
515+ cursor: pointer;
516+ font-size: 14px;
517+ transition: background 0.3s;
518+ }
519+ .retry-button:hover {
520+ background: #0b7dda;
521+ }
522+ </style>
523+ ` ) ;
0 commit comments