|
5 | 5 |
|
6 | 6 | $current_page = Page.Flasher; |
7 | 7 | let selectedVersion = $state('Last'); |
| 8 | + let selectedReleaseDate = $state(''); |
8 | 9 | let selectedDevice = $state(''); |
9 | 10 | let selectedCategory = $state(''); |
| 11 | + let versionTags: Array<{ tag_name: string; updated_at: string }> = $state([]); |
10 | 12 |
|
11 | 13 | $effect(() => { |
12 | 14 | updateManifest(); |
13 | 15 | }); |
14 | 16 |
|
| 17 | + function formatDateTime(str) { |
| 18 | + let date = new Date(str).toLocaleDateString(); |
| 19 | + let time = new Date(str).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); |
| 20 | + return `${date} ${time}`; |
| 21 | + } |
| 22 | +
|
15 | 23 | function downloadFile(file: string) { |
16 | 24 | const releaseTag = |
17 | 25 | selectedVersion === 'Beta' |
|
40 | 48 | selectedVersion = version; |
41 | 49 | const otherReleaseContainer = document.getElementById('otherReleaseContainer'); |
42 | 50 | otherReleaseContainer.style.display = version === 'Other' ? 'block' : 'none'; |
| 51 | + updateReleaseDate(); |
| 52 | + } |
| 53 | +
|
| 54 | + function updateReleaseDate() { |
| 55 | + let element: HTMLElement | null = null; |
| 56 | +
|
| 57 | + if (selectedVersion === 'Other') { |
| 58 | + const dropdown = document.getElementById('otherReleaseDropdown') as HTMLSelectElement; |
| 59 | + element = dropdown?.options[dropdown.selectedIndex]; |
| 60 | + } else { |
| 61 | + element = document.getElementById(selectedVersion === 'Last' ? 'latest' : 'beta'); |
| 62 | + } |
| 63 | +
|
| 64 | + selectedReleaseDate = element?.getAttribute('data-release-date') || ''; |
| 65 | +
|
| 66 | + document.getElementById('releaseDate').classList.remove('invisible'); |
43 | 67 | } |
44 | 68 |
|
45 | 69 | function findDeviceById(id) { |
|
96 | 120 | const active_el = (first: string, cmp: string) => (first == cmp ? 'bg-[#9B51E0] text-white' : ''); |
97 | 121 |
|
98 | 122 | // Get GitHub release tags |
99 | | - let versionTags: string[] = $state([]); |
100 | 123 | let latestVersionTag: string = $state(''); |
| 124 | + let latestVersionReleaseDate: string = $state(''); |
101 | 125 | let loading = $state(true); |
102 | 126 | let error = $state(''); |
103 | 127 |
|
|
111 | 135 | loading = true; |
112 | 136 | error = ''; |
113 | 137 | try { |
114 | | - const res = await fetch(`https://api.github.com/repos/${repo}/tags`); |
| 138 | + const res = await fetch(`https://api.github.com/repos/${repo}/releases?per_page=100`); |
115 | 139 | if (!res.ok) throw new Error('Failed to fetch tags'); |
116 | 140 | const data = await res.json(); |
117 | | - // Only include tags matching x.x or x.x.x |
118 | | - versionTags = data.map((tag: { name: string }) => tag.name).filter((name: string) => /^\d+\.\d+(\.\d+)?$/.test(name)); |
119 | | - latestVersionTag = versionTags.length > 0 ? versionTags[0] : ''; |
| 141 | + // Only include tags matching x.x or x.x.x, keep both tag_name and updated_at |
| 142 | + versionTags = data.map((release: { tag_name: string; updated_at: string }) => ({ |
| 143 | + tag_name: release.tag_name, |
| 144 | + updated_at: release.updated_at |
| 145 | + })); |
| 146 | + latestVersionTag = versionTags.length > 0 ? versionTags[0].tag_name : ''; |
| 147 | + latestVersionReleaseDate = versionTags.length > 0 ? versionTags[0].updated_at : ''; |
| 148 | + document.getElementById('latest').setAttribute('data-release-date', latestVersionReleaseDate); |
| 149 | + selectedReleaseDate = latestVersionReleaseDate; |
| 150 | +
|
| 151 | + const betaRelease = versionTags.find((r) => r.tag_name === 'betaRelease'); |
| 152 | + document.getElementById('beta').setAttribute('data-release-date', betaRelease.updated_at); |
| 153 | +
|
| 154 | + updateReleaseDate(); |
120 | 155 | } catch (e) { |
121 | 156 | error = e.message; |
122 | 157 | } |
|
196 | 231 | <select |
197 | 232 | id="otherReleaseDropdown" |
198 | 233 | class="mt-2 min-h-[2.5rem] w-32 min-w-[10rem] rounded-lg border-2 border-purple-500 bg-black p-2 px-5 py-2.5 text-purple-500 transition-all duration-300 ease-in-out" |
| 234 | + onchange={() => updateReleaseDate()} |
199 | 235 | > |
200 | | - {#each versionTags as versionTag, i (versionTag)} |
201 | | - <option value={versionTag}>{versionTag}{i === 0 ? ' (Latest)' : ''}</option> |
| 236 | + {#each versionTags.filter( (release: { tag_name: string }) => /^v?\d+\.\d+(\.\d+)?$/.test(release.tag_name) ) as versionTag, i (versionTag.tag_name)} |
| 237 | + <option value={versionTag.tag_name} data-release-date={versionTag.updated_at}>{versionTag.tag_name}{i === 0 ? ' (Latest)' : ''}</option> |
202 | 238 | {/each} |
203 | 239 | </select> |
204 | 240 | {/if} |
205 | 241 | </div> |
206 | 242 | </div> |
207 | 243 | </div> |
| 244 | + <div id="releaseDate" class="invisible mt-2 text-center text-sm font-bold text-gray-400" data-i18n="release_date"> |
| 245 | + Released: <span id="releaseDateValue" class="font-normal">{formatDateTime(selectedReleaseDate)}</span> |
| 246 | + </div> |
208 | 247 | </div> |
209 | 248 |
|
210 | 249 | <div class="container"> |
|
0 commit comments