diff --git a/Frontend/Electron/main.cjs b/Frontend/Electron/main.cjs
index f191424..ca35819 100644
--- a/Frontend/Electron/main.cjs
+++ b/Frontend/Electron/main.cjs
@@ -346,6 +346,44 @@ app.whenReady().then(async () => {
}
});
+ // Flatpak update check
+ ipcMain.handle('check-flatpak-update', async () => {
+ const isFlatpak = fs.existsSync('/.flatpak-info') || !!process.env.FLATPAK_ID;
+ if (!isFlatpak) return { isFlatpak: false };
+
+ try {
+ const yaml = await httpGet('https://gitea.moyettes.com/Moyettes/DiscordClone/releases/download/latest/latest-linux.yml');
+ if (!yaml) return { isFlatpak: true, updateAvailable: false };
+
+ const versionMatch = yaml.match(/^version:\s*(.+)$/m);
+ if (!versionMatch) return { isFlatpak: true, updateAvailable: false };
+
+ const latestVersion = versionMatch[1].trim();
+ const currentVersion = app.getVersion();
+
+ // Semver comparison: determine if update exists and its severity
+ const latest = latestVersion.split('.').map(Number);
+ const current = currentVersion.split('.').map(Number);
+ let updateAvailable = false;
+ let updateType = 'patch'; // 'major', 'minor', or 'patch'
+ for (let i = 0; i < Math.max(latest.length, current.length); i++) {
+ const l = latest[i] || 0;
+ const c = current[i] || 0;
+ if (l > c) {
+ updateAvailable = true;
+ updateType = i === 0 ? 'major' : i === 1 ? 'minor' : 'patch';
+ break;
+ }
+ if (l < c) break;
+ }
+
+ return { isFlatpak: true, updateAvailable, updateType, latestVersion, currentVersion };
+ } catch (err) {
+ console.error('Flatpak update check error:', err.message);
+ return { isFlatpak: true, updateAvailable: false };
+ }
+ });
+
ipcMain.handle('open-external', async (event, url) => {
await shell.openExternal(url);
});
diff --git a/Frontend/Electron/preload.cjs b/Frontend/Electron/preload.cjs
index 5b9c222..3f11439 100644
--- a/Frontend/Electron/preload.cjs
+++ b/Frontend/Electron/preload.cjs
@@ -32,6 +32,10 @@ contextBridge.exposeInMainWorld('appSettings', {
set: (key, value) => ipcRenderer.invoke('set-setting', key, value),
});
+contextBridge.exposeInMainWorld('updateAPI', {
+ checkFlatpakUpdate: () => ipcRenderer.invoke('check-flatpak-update'),
+});
+
contextBridge.exposeInMainWorld('sessionPersistence', {
save: (data) => ipcRenderer.invoke('save-session', data),
load: () => ipcRenderer.invoke('load-session'),
diff --git a/Frontend/Electron/src/components/TitleBar.jsx b/Frontend/Electron/src/components/TitleBar.jsx
index 1c4aa9c..7949f04 100644
--- a/Frontend/Electron/src/components/TitleBar.jsx
+++ b/Frontend/Electron/src/components/TitleBar.jsx
@@ -1,4 +1,5 @@
import React from 'react';
+import { TitleBarUpdateIcon } from './UpdateBanner';
const TitleBar = () => {
return (
@@ -26,6 +27,7 @@ const TitleBar = () => {
Discord Clone
+