mirror of
https://github.com/pommee/goaway.git
synced 2026-05-02 22:49:12 -05:00
feat: confetti for everyone when updating
This commit is contained in:
@@ -835,12 +835,14 @@ func (api *API) runUpdate(c *gin.Context) {
|
||||
flusher.Flush()
|
||||
}
|
||||
|
||||
sendSSE("[INFO] Starting update process...")
|
||||
sendSSE("[i] Starting update process...")
|
||||
err := updater.SelfUpdate(sendSSE)
|
||||
if err != nil {
|
||||
sendSSE(fmt.Sprintf("[ERROR] Update failed: %s", err.Error()))
|
||||
c.Status(http.StatusBadRequest)
|
||||
} else {
|
||||
sendSSE("[INFO] Update successful!")
|
||||
sendSSE("[i] Update successful!")
|
||||
c.Status(http.StatusOK)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,15 +4,16 @@ import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type sendSSE func(string)
|
||||
|
||||
func SelfUpdate(sse sendSSE) error {
|
||||
sse("[INFO] Loading update script")
|
||||
sse("[i] Loading update script")
|
||||
scriptPath := "./updater.sh"
|
||||
|
||||
sse("[INFO] Executing update script")
|
||||
sse("[i] Executing update script")
|
||||
cmd := exec.Command("bash", scriptPath)
|
||||
|
||||
stdoutPipe, err := cmd.StdoutPipe()
|
||||
@@ -28,10 +29,17 @@ func SelfUpdate(sse sendSSE) error {
|
||||
return fmt.Errorf("failed to start command: %v", err)
|
||||
}
|
||||
|
||||
done := make(chan struct{})
|
||||
|
||||
go func() {
|
||||
scanner := bufio.NewScanner(stdoutPipe)
|
||||
for scanner.Scan() {
|
||||
sse(scanner.Text())
|
||||
text := scanner.Text()
|
||||
if strings.Contains(text, "Stopping") {
|
||||
close(done)
|
||||
return
|
||||
}
|
||||
sse(text)
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -42,9 +50,22 @@ func SelfUpdate(sse sendSSE) error {
|
||||
}
|
||||
}()
|
||||
|
||||
if err := cmd.Wait(); err != nil {
|
||||
return fmt.Errorf("update failed: %v", err)
|
||||
select {
|
||||
case <-done:
|
||||
return nil
|
||||
case err := <-waitCmd(cmd):
|
||||
if err != nil {
|
||||
return fmt.Errorf("update failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func waitCmd(cmd *exec.Cmd) <-chan error {
|
||||
ch := make(chan error, 1)
|
||||
go func() {
|
||||
ch <- cmd.Wait()
|
||||
}()
|
||||
return ch
|
||||
}
|
||||
|
||||
+5
-5
@@ -14,19 +14,19 @@ if [[ -z "$ASSET_URL" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[INFO] Downloading $BINARY_NAME version $LATEST_VERSION..."
|
||||
echo "[i] Downloading $BINARY_NAME version $LATEST_VERSION..."
|
||||
curl -L -o "$TMP_DIR/$BINARY_NAME.tar.gz" "$ASSET_URL"
|
||||
|
||||
echo "[INFO] Extracting $BINARY_NAME..."
|
||||
echo "[i] Extracting $BINARY_NAME..."
|
||||
tar -xzf "$TMP_DIR/$BINARY_NAME.tar.gz" -C "$TMP_DIR"
|
||||
|
||||
echo "[INFO] Stopping $BINARY_NAME..."
|
||||
echo "[i] Stopping $BINARY_NAME..."
|
||||
pkill $BINARY_NAME
|
||||
|
||||
echo "[INFO] Moving binary $TMP_DIR/$BINARY_NAME"
|
||||
echo "[i] Moving binary $TMP_DIR/$BINARY_NAME"
|
||||
mv "$TMP_DIR/$BINARY_NAME" "$INSTALL_DIR/$BINARY_NAME"
|
||||
|
||||
echo "[INFO] Starting goaway again..."
|
||||
echo "[i] Starting goaway again..."
|
||||
exec $ORIGINAL_CMD
|
||||
|
||||
rm -rf "$TMP_DIR"
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
"@radix-ui/react-tooltip": "^1.1.8",
|
||||
"@tailwindcss/vite": "^4.0.17",
|
||||
"@tanstack/react-table": "^8.21.2",
|
||||
"canvas-confetti": "^1.9.3",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"cmdk": "1.0.0",
|
||||
|
||||
Generated
+8
@@ -50,6 +50,9 @@ importers:
|
||||
'@tanstack/react-table':
|
||||
specifier: ^8.21.2
|
||||
version: 8.21.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
canvas-confetti:
|
||||
specifier: ^1.9.3
|
||||
version: 1.9.3
|
||||
class-variance-authority:
|
||||
specifier: ^0.7.1
|
||||
version: 0.7.1
|
||||
@@ -1394,6 +1397,9 @@ packages:
|
||||
caniuse-lite@1.0.30001707:
|
||||
resolution: {integrity: sha512-3qtRjw/HQSMlDWf+X79N206fepf4SOOU6SQLMaq/0KkZLmSjPxAkBOQQ+FxbHKfHmYLZFfdWsO3KA90ceHPSnw==}
|
||||
|
||||
canvas-confetti@1.9.3:
|
||||
resolution: {integrity: sha512-rFfTURMvmVEX1gyXFgn5QMn81bYk70qa0HLzcIOSVEyl57n6o9ItHeBtUSWdvKAPY0xlvBHno4/v3QPrT83q9g==}
|
||||
|
||||
chalk@4.1.2:
|
||||
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -3431,6 +3437,8 @@ snapshots:
|
||||
|
||||
caniuse-lite@1.0.30001707: {}
|
||||
|
||||
canvas-confetti@1.9.3: {}
|
||||
|
||||
chalk@4.1.2:
|
||||
dependencies:
|
||||
ansi-styles: 4.3.0
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
} from "@/components/ui/dialog";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { DialogDescription } from "@radix-ui/react-dialog";
|
||||
import confetti from "canvas-confetti";
|
||||
|
||||
export type Metrics = {
|
||||
cpuTemp: number;
|
||||
@@ -75,17 +76,18 @@ export function ServerStatistics() {
|
||||
useEffect(() => {
|
||||
async function fetchData() {
|
||||
try {
|
||||
const [, data] = await GetRequest("server");
|
||||
setMetrics(data);
|
||||
setNewVersion(data.version);
|
||||
|
||||
let installedVersion = localStorage.getItem("installedVersion");
|
||||
const newestVersion = localStorage.getItem("newestVersion");
|
||||
|
||||
const [, data] = await GetRequest("server");
|
||||
setMetrics(data);
|
||||
|
||||
if (installedVersion === null) {
|
||||
localStorage.setItem("installedVersion", data.version);
|
||||
installedVersion = localStorage.getItem("installedVersion");
|
||||
}
|
||||
if (newestVersion !== null) {
|
||||
setNewVersion(newestVersion);
|
||||
if (
|
||||
installedVersion &&
|
||||
!updateNotified &&
|
||||
@@ -117,13 +119,23 @@ export function ServerStatistics() {
|
||||
|
||||
eventSource.onmessage = (event) => {
|
||||
setUpdateLogs((logs) => [...logs, event.data]);
|
||||
|
||||
if (event.data.includes("Update successful")) {
|
||||
toast.info("Updated!", { description: `Now running v${newVersion}` });
|
||||
localStorage.setItem("installedVersion", newVersion);
|
||||
eventSource.close();
|
||||
confetti({
|
||||
particleCount: 100,
|
||||
spread: 70,
|
||||
origin: { y: 0.6 },
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
eventSource.onerror = () => {
|
||||
setUpdateLogs((logs) => [...logs, "Closing event stream..."]);
|
||||
eventSource.close();
|
||||
};
|
||||
localStorage.setItem("installedVersion", newVersion);
|
||||
}
|
||||
|
||||
const formatNumber = (num: number) => num.toFixed(1);
|
||||
|
||||
Reference in New Issue
Block a user