1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
import { definePlugin } from "decky-frontend-lib";
import React, { useEffect, useState } from "react";
import { FaClipboardList } from "react-icons/fa";
function Content() {
const [changelog, setChangelog] = useState<string | null>(null);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
const url =
"https://api.github.com/repos/ublue-os/bazzite/releases/tags/41.20250106.2";
const controller = new AbortController();
const signal = controller.signal;
const fetchChangelog = async () => {
try {
const response = await fetch(url, {
headers: {
Accept: "application/vnd.github.v3+json",
},
signal,
});
if (!response.ok) {
throw new Error(`Failed to fetch: ${response.statusText}`);
}
const data = await response.json();
setChangelog(data.body);
} catch (err) {
if (err instanceof DOMException && err.name === "AbortError") return;
const errorMessage =
err instanceof Error
? err.message
: "An unknown error occurred while fetching the changelog.";
setError(errorMessage);
}
};
fetchChangelog();
return () => {
controller.abort(); // Cleanup on unmount
};
}, []);
return (
<div
style={{
padding: "10px",
width: "100%",
height: "100%",
overflowY: "auto",
backgroundColor: "#121212",
color: "#ffffff",
fontFamily: "Arial, sans-serif",
}}
>
<h2>Bazzite Release Notes</h2>
{error ? (
<p style={{ color: "red" }} aria-live="polite">
{error}
</p>
) : changelog ? (
<pre
style={{
whiteSpace: "pre-wrap",
wordWrap: "break-word",
}}
>
{changelog}
</pre>
) : (
<p aria-live="polite">Loading...</p>
)}
</div>
);
}
export default definePlugin(() => {
return {
name: "Bazzite Changelog Viewer",
title: <div>Bazzite Changelog</div>,
icon: <FaClipboardList />,
content: <Content />,
onDismount() {},
};
});
|