broadfield-dev commited on
Commit
ec48712
·
verified ·
1 Parent(s): 1c9f24c

Update templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +102 -53
templates/index.html CHANGED
@@ -80,76 +80,103 @@
80
  <script>
81
  let lastUpdate = 0;
82
  let expandedCategories = new Set();
 
 
 
 
 
 
 
 
 
 
 
 
83
  function getArticleKey(article) {
84
  return `${article.title}|${article.link}|${article.published}`;
85
  }
86
- function toggleCategory(category) {
 
87
  const spinner = document.getElementById(`spinner-${category}`);
88
  const tilesDiv = document.getElementById(`category-${category}`);
89
  const allTilesDiv = document.getElementById(`all-${category}`);
 
90
  if (expandedCategories.has(category)) {
91
  tilesDiv.style.display = 'grid';
92
  allTilesDiv.style.display = 'none';
93
  expandedCategories.delete(category);
94
  } else {
95
- spinner.style.display = 'inline-block';
96
- fetch(`/get_all_articles/${category}`)
97
- .then(response => response.json())
98
- .then(data => {
99
- spinner.style.display = 'none';
100
- if (data.articles.length > 0) {
101
- let html = '';
102
- const seenKeys = new Set();
103
- data.articles.sort((a, b) => new Date(b.published) - new Date(a.published));
104
- data.articles.forEach((article, index) => {
105
- const key = getArticleKey(article);
106
- if (!seenKeys.has(key)) {
107
- seenKeys.add(key);
108
- html += `
109
- <div class="article-tile" data-published="${article.published}" data-id="${index}" data-key="${key}">
110
- ${article.image !== "svg" ? `<img src="${article.image}" alt="Article Image">` : `
111
- <svg width="100%" height="150" xmlns="http://www.w3.org/2000/svg">
112
- <rect width="100%" height="100%" fill="#e0e0e0"/>
113
- <text x="50%" y="50%" text-anchor="middle" dy=".3em" fill="#666">No Image</text>
114
- </svg>
115
- `}
116
- <div class="title"><a href="${article.link}" target="_blank">${article.title}</a></div>
117
- <div class="description">${article.description}</div>
118
- <div class="published">Published: ${article.published}</div>
119
- </div>
120
- `;
121
- } else {
122
- console.warn(`Duplicate article skipped in category ${category}: ${key}`);
123
- }
124
- });
125
- tilesDiv.style.display = 'none';
126
- allTilesDiv.innerHTML = html;
127
- allTilesDiv.style.display = 'grid';
128
- expandedCategories.add(category);
129
- } else {
130
- alert(`No additional articles found for ${category}.`);
131
- }
132
- })
133
- .catch(error => {
134
- spinner.style.display = 'none';
135
- console.error(`Error loading all articles for ${category}:`, error);
136
- alert(`Failed to load all articles for ${category}. Please try again.`);
137
- });
 
 
 
 
 
 
138
  }
 
 
 
139
  }
 
140
  function updateArticles() {
141
  fetch('/get_updates')
142
  .then(response => response.json())
143
  .then(data => {
144
- if (data.articles && data.last_update > lastUpdate) {
145
  lastUpdate = data.last_update;
146
  const newArticles = data.articles;
 
 
 
 
147
  for (const [category, articles] of Object.entries(newArticles)) {
148
  const tilesDiv = document.getElementById(`category-${category}`);
149
  const allTilesDiv = document.getElementById(`all-${category}`);
150
  if (tilesDiv) {
151
  const existingArticles = Array.from(tilesDiv.querySelectorAll('.article-tile'));
152
- let currentIds = new Set(existingArticles.map(a => a.dataset.id));
153
  let currentKeys = new Set(existingArticles.map(a => a.dataset.key));
154
  let newHtml = '';
155
  articles.sort((a, b) => new Date(b.published) - new Date(a.published));
@@ -173,11 +200,17 @@
173
  console.warn(`Duplicate article skipped in update for ${category}: ${key}`);
174
  }
175
  });
 
176
  if (newHtml) {
177
  tilesDiv.innerHTML = (existingArticles.map(a => a.outerHTML).join('') + newHtml);
178
  const allLimited = Array.from(tilesDiv.querySelectorAll('.article-tile'));
179
- tilesDiv.innerHTML = allLimited.sort((a, b) => new Date(b.dataset.published) - new Date(a.dataset.published)).slice(0, 10).map(a => a.outerHTML).join('');
 
 
 
 
180
  }
 
181
  if (allTilesDiv.style.display === 'grid') {
182
  let allNewHtml = '';
183
  const allSeenKeys = new Set(Array.from(allTilesDiv.querySelectorAll('.article-tile')).map(a => a.dataset.key));
@@ -204,26 +237,39 @@
204
  });
205
  allTilesDiv.innerHTML = (Array.from(allTilesDiv.querySelectorAll('.article-tile')).map(a => a.outerHTML).join('') + allNewHtml);
206
  const allExpanded = Array.from(allTilesDiv.querySelectorAll('.article-tile'));
207
- allTilesDiv.innerHTML = allExpanded.sort((a, b) => new Date(b.dataset.published) - new Date(a.dataset.published)).map(a => a.outerHTML).join('');
 
 
 
208
  }
209
  }
210
  }
 
 
 
211
  }
212
- setTimeout(updateArticles, 2000);
 
 
213
  })
214
  .catch(error => {
215
  console.error('Error updating articles:', error);
216
- setTimeout(updateArticles, 2000);
217
  });
218
  }
 
219
  function checkLoadingStatus() {
220
  fetch('/check_loading')
221
  .then(response => response.json())
222
  .then(data => {
223
  if (data.status === 'complete') {
224
- window.location.reload(); // Refresh the page when loading is complete
 
 
 
 
225
  } else {
226
- setTimeout(checkLoadingStatus, 2000); // Check again after 2 seconds
227
  }
228
  })
229
  .catch(error => {
@@ -231,16 +277,18 @@
231
  setTimeout(checkLoadingStatus, 2000);
232
  });
233
  }
 
234
  document.addEventListener('DOMContentLoaded', () => {
235
  const tiles = document.querySelectorAll('.tiles');
236
  tiles.forEach(tile => {
237
  lastUpdate = Math.max(lastUpdate, parseFloat(tile.dataset.lastUpdate) || 0);
238
  });
239
- updateArticles();
240
  // Start checking loading status if loading is active
241
  if (document.getElementById('loadingContainer')) {
242
  checkLoadingStatus();
243
  }
 
244
  const form = document.getElementById('searchForm');
245
  const backButton = document.getElementById('backButton');
246
  form.addEventListener('submit', (event) => {
@@ -301,6 +349,7 @@
301
  alert('Failed to perform search. Please try again.');
302
  });
303
  });
 
304
  backButton.addEventListener('click', () => {
305
  window.location.href = '/';
306
  });
 
80
  <script>
81
  let lastUpdate = 0;
82
  let expandedCategories = new Set();
83
+
84
+ // Restore expanded categories from session storage if available
85
+ document.addEventListener('DOMContentLoaded', () => {
86
+ const storedExpanded = sessionStorage.getItem('expandedCategories');
87
+ if (storedExpanded) {
88
+ expandedCategories = new Set(JSON.parse(storedExpanded));
89
+ expandedCategories.forEach(category => {
90
+ toggleCategory(category, false); // Expand without fetching
91
+ });
92
+ }
93
+ });
94
+
95
  function getArticleKey(article) {
96
  return `${article.title}|${article.link}|${article.published}`;
97
  }
98
+
99
+ function toggleCategory(category, fetchData = true) {
100
  const spinner = document.getElementById(`spinner-${category}`);
101
  const tilesDiv = document.getElementById(`category-${category}`);
102
  const allTilesDiv = document.getElementById(`all-${category}`);
103
+
104
  if (expandedCategories.has(category)) {
105
  tilesDiv.style.display = 'grid';
106
  allTilesDiv.style.display = 'none';
107
  expandedCategories.delete(category);
108
  } else {
109
+ if (fetchData) {
110
+ spinner.style.display = 'inline-block';
111
+ fetch(`/get_all_articles/${category}`)
112
+ .then(response => response.json())
113
+ .then(data => {
114
+ spinner.style.display = 'none';
115
+ if (data.articles.length > 0) {
116
+ let html = '';
117
+ const seenKeys = new Set();
118
+ data.articles.sort((a, b) => new Date(b.published) - new Date(a.published));
119
+ data.articles.forEach((article, index) => {
120
+ const key = getArticleKey(article);
121
+ if (!seenKeys.has(key)) {
122
+ seenKeys.add(key);
123
+ html += `
124
+ <div class="article-tile" data-published="${article.published}" data-id="${index}" data-key="${key}">
125
+ ${article.image !== "svg" ? `<img src="${article.image}" alt="Article Image">` : `
126
+ <svg width="100%" height="150" xmlns="http://www.w3.org/2000/svg">
127
+ <rect width="100%" height="100%" fill="#e0e0e0"/>
128
+ <text x="50%" y="50%" text-anchor="middle" dy=".3em" fill="#666">No Image</text>
129
+ </svg>
130
+ `}
131
+ <div class="title"><a href="${article.link}" target="_blank">${article.title}</a></div>
132
+ <div class="description">${article.description}</div>
133
+ <div class="published">Published: ${article.published}</div>
134
+ </div>
135
+ `;
136
+ } else {
137
+ console.warn(`Duplicate article skipped in category ${category}: ${key}`);
138
+ }
139
+ });
140
+ tilesDiv.style.display = 'none';
141
+ allTilesDiv.innerHTML = html;
142
+ allTilesDiv.style.display = 'grid';
143
+ expandedCategories.add(category);
144
+ } else {
145
+ alert(`No additional articles found for ${category}.`);
146
+ }
147
+ })
148
+ .catch(error => {
149
+ spinner.style.display = 'none';
150
+ console.error(`Error loading all articles for ${category}:`, error);
151
+ alert(`Failed to load all articles for ${category}. Please try again.`);
152
+ });
153
+ } else {
154
+ tilesDiv.style.display = 'none';
155
+ allTilesDiv.style.display = 'grid';
156
+ expandedCategories.add(category);
157
+ }
158
  }
159
+
160
+ // Save expanded categories to session storage
161
+ sessionStorage.setItem('expandedCategories', JSON.stringify([...expandedCategories]));
162
  }
163
+
164
  function updateArticles() {
165
  fetch('/get_updates')
166
  .then(response => response.json())
167
  .then(data => {
168
+ if (data.has_updates && data.last_update > lastUpdate) {
169
  lastUpdate = data.last_update;
170
  const newArticles = data.articles;
171
+
172
+ // Store the current scroll position and expanded categories
173
+ const scrollPosition = window.scrollY;
174
+
175
  for (const [category, articles] of Object.entries(newArticles)) {
176
  const tilesDiv = document.getElementById(`category-${category}`);
177
  const allTilesDiv = document.getElementById(`all-${category}`);
178
  if (tilesDiv) {
179
  const existingArticles = Array.from(tilesDiv.querySelectorAll('.article-tile'));
 
180
  let currentKeys = new Set(existingArticles.map(a => a.dataset.key));
181
  let newHtml = '';
182
  articles.sort((a, b) => new Date(b.published) - new Date(a.published));
 
200
  console.warn(`Duplicate article skipped in update for ${category}: ${key}`);
201
  }
202
  });
203
+
204
  if (newHtml) {
205
  tilesDiv.innerHTML = (existingArticles.map(a => a.outerHTML).join('') + newHtml);
206
  const allLimited = Array.from(tilesDiv.querySelectorAll('.article-tile'));
207
+ tilesDiv.innerHTML = allLimited
208
+ .sort((a, b) => new Date(b.dataset.published) - new Date(a.dataset.published))
209
+ .slice(0, 10)
210
+ .map(a => a.outerHTML)
211
+ .join('');
212
  }
213
+
214
  if (allTilesDiv.style.display === 'grid') {
215
  let allNewHtml = '';
216
  const allSeenKeys = new Set(Array.from(allTilesDiv.querySelectorAll('.article-tile')).map(a => a.dataset.key));
 
237
  });
238
  allTilesDiv.innerHTML = (Array.from(allTilesDiv.querySelectorAll('.article-tile')).map(a => a.outerHTML).join('') + allNewHtml);
239
  const allExpanded = Array.from(allTilesDiv.querySelectorAll('.article-tile'));
240
+ allTilesDiv.innerHTML = allExpanded
241
+ .sort((a, b) => new Date(b.dataset.published) - new Date(a.dataset.published))
242
+ .map(a => a.outerHTML)
243
+ .join('');
244
  }
245
  }
246
  }
247
+
248
+ // Restore scroll position
249
+ window.scrollTo(0, scrollPosition);
250
  }
251
+
252
+ // Schedule the next update
253
+ setTimeout(updateArticles, 30000); // Poll every 30 seconds
254
  })
255
  .catch(error => {
256
  console.error('Error updating articles:', error);
257
+ setTimeout(updateArticles, 30000);
258
  });
259
  }
260
+
261
  function checkLoadingStatus() {
262
  fetch('/check_loading')
263
  .then(response => response.json())
264
  .then(data => {
265
  if (data.status === 'complete') {
266
+ const loadingContainer = document.getElementById('loadingContainer');
267
+ if (loadingContainer) {
268
+ loadingContainer.style.display = 'none';
269
+ }
270
+ updateArticles(); // Start polling for updates
271
  } else {
272
+ setTimeout(checkLoadingStatus, 2000);
273
  }
274
  })
275
  .catch(error => {
 
277
  setTimeout(checkLoadingStatus, 2000);
278
  });
279
  }
280
+
281
  document.addEventListener('DOMContentLoaded', () => {
282
  const tiles = document.querySelectorAll('.tiles');
283
  tiles.forEach(tile => {
284
  lastUpdate = Math.max(lastUpdate, parseFloat(tile.dataset.lastUpdate) || 0);
285
  });
286
+
287
  // Start checking loading status if loading is active
288
  if (document.getElementById('loadingContainer')) {
289
  checkLoadingStatus();
290
  }
291
+
292
  const form = document.getElementById('searchForm');
293
  const backButton = document.getElementById('backButton');
294
  form.addEventListener('submit', (event) => {
 
349
  alert('Failed to perform search. Please try again.');
350
  });
351
  });
352
+
353
  backButton.addEventListener('click', () => {
354
  window.location.href = '/';
355
  });