1
+ ---
2
+ import { DownloadIcon } from " ../base/icons/DownloadIcon" ;
3
+ import { CheckIcon } from " ../base/icons/CheckIcon" ;
4
+ import { PlatformType } from " ../base/types/platform" ;
5
+
6
+ interface Props {
7
+ repoUrl: string ;
8
+ }
9
+
10
+ const { repoUrl } = Astro .props ;
11
+
12
+ // Extract owner and repo from the URL
13
+ const urlParts = repoUrl .split (' /' );
14
+ const owner = urlParts [urlParts .length - 2 ];
15
+ const repo = urlParts [urlParts .length - 1 ];
16
+
17
+ // Fetch releases from GitHub API
18
+ const response = await fetch (
19
+ ` https://api.github.com/repos/${owner }/${repo }/releases?per_page=10 `
20
+ );
21
+ const releases = await response .json ();
22
+
23
+ // Filter only stable releases (not pre-releases) and get the latest one
24
+ const stableReleases = releases .filter ((release : any ) => ! release .prerelease );
25
+ const latestRelease = stableReleases [0 ]; // Get only the latest release
26
+
27
+ interface Asset {
28
+ name: string ;
29
+ browser_download_url: string ;
30
+ size: number ;
31
+ }
32
+
33
+ function getAssetDescription(assetName : string ): string {
34
+ // Mapping based on provided examples
35
+ if (/ \. deb$ / .test (assetName ) && / x86_64-unknown-linux-gnu/ .test (assetName )) {
36
+ return " Debian / Ubuntu (x64)" ;
37
+ }
38
+ if (/ \. rpm$ / .test (assetName ) && / x86_64-unknown-linux-gnu/ .test (assetName )) {
39
+ return " Red Hat / Fedora (x64)" ;
40
+ }
41
+ if (/ \. pkg$ / .test (assetName ) && / x86_64-unknown-freebsd/ .test (assetName )) {
42
+ return " FreeBSD (x64, pkg)" ;
43
+ }
44
+ if (/ \. tar\. gz$ / .test (assetName ) && / aarch64-unknown-linux-gnu/ .test (assetName )) {
45
+ return " Linux (ARM64, tar.gz)" ;
46
+ }
47
+ if (/ \. tar\. gz$ / .test (assetName ) && / x86_64-unknown-freebsd/ .test (assetName )) {
48
+ return " FreeBSD (x64, tar.gz)" ;
49
+ }
50
+ if (/ \. tar\. gz$ / .test (assetName ) && / x86_64-unknown-linux-gnu/ .test (assetName )) {
51
+ return " Linux (x64, tar.gz)" ;
52
+ }
53
+ return " " ;
54
+ }
55
+
56
+ function getPlatformType(assetName : string ): PlatformType {
57
+ if (assetName .includes (' windows' )) return PlatformType .WINDOWS ;
58
+ if (assetName .includes (' linux' ) && assetName .includes (' .deb' )) return PlatformType .DEBIAN ;
59
+ if (assetName .includes (' macos' ) && (assetName .includes (' aarch64' ) || assetName .includes (' arm64' ))) return PlatformType .MACOSARM ;
60
+ if (assetName .includes (' macos' ) && (assetName .includes (' x86_64' ) || assetName .includes (' amd64' ))) return PlatformType .MACOSINTEL ;
61
+ return PlatformType .DEBIAN ; // Default to Debian if unknown
62
+ }
63
+ ---
64
+
65
+ <div class =" github-releases" >
66
+ { latestRelease && (
67
+ <div class = " release-container" >
68
+ <div class = " release-header" >
69
+ <div class = " release-version-info" >
70
+ Latest stable release: { latestRelease .tag_name .replace (/ ^ v/ , " " )} | View changelog →
71
+ <a href = { latestRelease .html_url } target = " _blank" rel = " noopener noreferrer" >
72
+ { new Date (latestRelease .published_at ).toLocaleDateString ()}
73
+ </a >
74
+ </div >
75
+ </div >
76
+ { latestRelease .assets && latestRelease .assets .length > 0 && (
77
+ <div class = " assets-container" >
78
+ <ul class = " assets-list" >
79
+ { (() => {
80
+ const assets = latestRelease .assets ;
81
+ const tarGzIndex = assets .findIndex ((a : any ) => a .name .includes (' .tar.gz' ));
82
+ return assets .map ((asset : any , idx : number ) => [
83
+ (idx === tarGzIndex && tarGzIndex !== 0 ) ? (
84
+ <li class = " asset-separator" >
85
+ <div class = " download-separator" >
86
+ <hr />
87
+ <p >compressed archives</p >
88
+ <hr />
89
+ </div >
90
+ </li >
91
+ ) : null ,
92
+ <li class = " asset-item" >
93
+ <a
94
+ href = { asset .browser_download_url }
95
+ target = " _blank"
96
+ rel = " noopener noreferrer"
97
+ class = " download-button-wrapper"
98
+ title = { ` Size: ${(asset .size / 1024 / 1024 ).toFixed (2 )} MB ` }
99
+ >
100
+ <div class = " download-text-wrapper" >
101
+ <span class = " download-filename" >Download now</span >
102
+ { getAssetDescription (asset .name ) && <p >{ getAssetDescription (asset .name )} </p >}
103
+ </div >
104
+ <DownloadIcon />
105
+ </a >
106
+ </li >
107
+ ]).flat ();
108
+ })()}
109
+ </ul >
110
+ <div class = " release-note" >
111
+ For pre-release archives, visit the
112
+ <a href = { ` https://github.com/${owner }/${repo }/releases ` } target = " _blank" rel = " noopener noreferrer" >GitHub Releases page</a >
113
+ to access all assets, including source code.
114
+ </div >
115
+ </div >
116
+ )}
117
+ </div >
118
+ )}
119
+ </div >
120
+
121
+ <style lang =" scss" >
122
+ .github-releases {
123
+ padding-top: 1rem;
124
+ background: var(--theme-card-bg);
125
+ border-radius: 8px;
126
+ }
127
+
128
+ h3 {
129
+ margin: 0 0 1rem 0;
130
+ color: var(--theme-text);
131
+ font-size: 1.2rem;
132
+ text-align: center;
133
+ }
134
+
135
+
136
+ .release-header {
137
+ margin-bottom: 0.5rem;
138
+ }
139
+
140
+ .release-version-info {
141
+ @include typography(pricebox-list);
142
+ margin-bottom: 20px;
143
+ line-height: 1.2;
144
+ font-size: 16px;
145
+
146
+ a {
147
+ text-decoration: underline;
148
+ color: inherit;
149
+ white-space: nowrap;
150
+ transition: color 0.2s;
151
+ }
152
+ a:hover {
153
+ color: #0c8ce0;
154
+ }
155
+ }
156
+
157
+ .assets-container {
158
+ margin-top: 0.5rem;
159
+ padding-left: 0;
160
+ }
161
+
162
+ .assets-list {
163
+ list-style: none;
164
+ padding: 0;
165
+ margin: 0;
166
+ display: flex;
167
+ flex-direction: column;
168
+ gap: 0.5rem;
169
+ }
170
+
171
+ .asset-item {
172
+ margin: 0;
173
+ padding: 0;
174
+ }
175
+
176
+ .download-button-wrapper {
177
+ display: flex;
178
+ height: 64px;
179
+ padding: 0px 20px;
180
+ justify-content: space-between;
181
+ align-items: center;
182
+ align-self: stretch;
183
+ border: 1px solid var(--text-body-primary);
184
+ text-decoration: none;
185
+ color: inherit;
186
+ cursor: pointer;
187
+ transition: all 0.2s ease;
188
+
189
+ // Default state for SVG
190
+ svg {
191
+ path {
192
+ stroke: currentColor;
193
+ transition: stroke 0.2s ease;
194
+ }
195
+ }
196
+
197
+ &:hover {
198
+ background-color: var(--surface-frame-bg);
199
+ border-color: #0c8ce0;
200
+ color: #0c8ce0; // Set color on the wrapper itself
201
+
202
+ .download-text-wrapper {
203
+ .download-filename {
204
+ color: #0c8ce0;
205
+ }
206
+ p {
207
+ color: var(--theme-text);
208
+ }
209
+ }
210
+
211
+ svg {
212
+ path {
213
+ stroke: currentColor; // Use currentColor to inherit from parent
214
+ }
215
+ }
216
+ }
217
+ }
218
+
219
+ .download-text-wrapper {
220
+ display: flex;
221
+ flex-direction: column;
222
+ justify-content: flex-start;
223
+ align-items: flex-start;
224
+ @include typography(paragraph);
225
+
226
+ .download-filename {
227
+ @include typography(paragraph);
228
+ font-size: calc(18px * var(--font-scale-factor));
229
+ color: var(--theme-text);
230
+ }
231
+
232
+ p {
233
+ @include typography(footer);
234
+ margin: 0;
235
+ color: var(--theme-text);
236
+ }
237
+ }
238
+
239
+ .btn {
240
+ all: unset;
241
+ padding: 20px;
242
+ svg {
243
+ path,
244
+ rect {
245
+ fill: none;
246
+ stroke: var(--text-body-primary);
247
+ transition: stroke 0.2s ease;
248
+ }
249
+ }
250
+ }
251
+
252
+ .download-separator {
253
+ display: flex;
254
+ align-items: center;
255
+ gap: 40px;
256
+ align-self: stretch;
257
+ text-align: center;
258
+ @include typography(footer);
259
+ padding-top: 1.5rem;
260
+ padding-bottom: 1.5rem;
261
+
262
+ hr {
263
+ flex: 1;
264
+ height: 1px;
265
+ background-color: var(--border-separator);
266
+ border: none;
267
+ margin: 0;
268
+ }
269
+
270
+ p {
271
+ width: 30%;
272
+ }
273
+ }
274
+
275
+ @include break-down(sm) {
276
+ P {
277
+ font-size: 12px;
278
+ font-weight: 300;
279
+ }
280
+ .download-separator p {
281
+ width: 30%;
282
+ }
283
+ }
284
+
285
+ .release-note {
286
+ margin-top: 2rem;
287
+ text-align: center;
288
+ @include typography(footer);
289
+ color: var(--theme-text-light);
290
+ a {
291
+ color: #0c8ce0;
292
+ text-decoration: underline;
293
+ transition: color 0.2s;
294
+ }
295
+ a:hover {
296
+ color: #005fa3;
297
+ }
298
+ }
299
+ </style >
0 commit comments