From 2c7a94441d88303d68351fb4e3692645f09b119e Mon Sep 17 00:00:00 2001 From: Kibi Kelburton Date: Thu, 1 Oct 2026 01:31:51 +0200 Subject: [PATCH] Add release builds, classic and stacked layouts - electron-builder packaging: AppImage, deb and tar.gz for Linux, NSIS installer for Windows, app icon, desktop entry - Gitea workflow builds Linux and Windows on version tags and attaches the files to the release - Layout setting in Appearance: Modern, Classic (chat left, channels right) and Stacked (channels on top, chat below, resizable split), like the desktop Mumble client - No message box while not connected; Manage identities on the welcome page - Public list: a list that arrives after the source changed no longer replaces the new one Co-Authored-By: Claude Opus 5.5 --- .gitea/workflows/release.yml | 40 +++++++++++++++++++ README.md | 17 ++++++-- build/icon.png | Bin 0 -> 15479 bytes build/icon.svg | 11 ++++++ electron/main.ts | 2 + package.json | 48 +++++++++++++++++++---- public/icon.png | Bin 0 -> 3396 bytes src/App.svelte | 64 +++++++++++++++++++++++-------- src/lib/settings.svelte.ts | 7 +++- src/ui/AppearanceSettings.svelte | 47 ++++++++++++++++++++++- src/ui/Chat.svelte | 11 ++++-- src/ui/PublicServers.svelte | 14 +++++-- src/ui/ResizeHandle.svelte | 21 +++++++--- src/ui/Sidebar.svelte | 10 +++-- test/e2e/app.e2e.ts | 37 ++++++++++++++++++ 15 files changed, 286 insertions(+), 43 deletions(-) create mode 100644 .gitea/workflows/release.yml create mode 100644 build/icon.png create mode 100644 build/icon.svg create mode 100644 public/icon.png diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml new file mode 100644 index 0000000..343f94f --- /dev/null +++ b/.gitea/workflows/release.yml @@ -0,0 +1,40 @@ +# Builds the Linux packages and the Windows installer when a version tag (v1.2.3) is pushed, +# and attaches them to a Gitea release of that tag. macOS builds need a Mac and are not made here. +name: release + +on: + push: + tags: ['v*'] + +jobs: + build: + runs-on: ubuntu-latest + # Has Wine, so the Windows installer builds on Linux + container: electronuserland/builder:wine + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 24 + - run: npm ci + - run: npm run check + - run: npm test + - run: npm run build + - run: npx electron-builder --linux --win --publish never + - name: Upload to the release + env: + TOKEN: ${{ secrets.GITHUB_TOKEN }} + API: ${{ github.server_url }}/api/v1/repos/${{ github.repository }} + TAG: ${{ github.ref_name }} + run: | + set -eu + release=$(curl -sf -H "Authorization: token $TOKEN" "$API/releases/tags/$TAG" || true) + if [ -z "$release" ]; then + release=$(curl -sf -X POST -H "Authorization: token $TOKEN" -H 'Content-Type: application/json' \ + -d "{\"tag_name\":\"$TAG\",\"name\":\"mumh5 $TAG\"}" "$API/releases") + fi + id=$(printf '%s' "$release" | node -e "let s='';process.stdin.on('data',d=>s+=d).on('end',()=>console.log(JSON.parse(s).id))") + for f in release/*.AppImage release/*.deb release/*.tar.gz release/*.exe; do + curl -sf -X POST -H "Authorization: token $TOKEN" -F "attachment=@$f" "$API/releases/$id/assets?name=$(basename "$f")" >/dev/null + echo "uploaded $(basename "$f")" + done diff --git a/README.md b/README.md index 74651d5..c3c7ae5 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ mumh5 keeps the foundation and replaces the experience. | | Mumble desktop | mumh5 | |---|---|---| -| Interface | Qt widgets, dense dialogs | Modern layout: server rail, channel tree, chat, side panels | +| Interface | Qt widgets, dense dialogs | Modern layout (server rail, channel tree, chat, side panels), or the classic and stacked layouts of the desktop client | | Several servers at the same time | One connection | Many; voice on one, text on all, unread badges | | Sharing files | Images only, pasted inline and heavily limited | Any allowed file through your own [f0ckm](#file-sharing-with-f0ckm) host, inline players for images, video and audio. Images still work without one | | YouTube links | Plain links | Click-to-play player (privacy mode), optional thumbnails | @@ -111,7 +111,18 @@ Dark, Light, Midnight (true black), Frost, and a faithful **Windows 95** theme w ## Getting started -There are no release builds yet. For now, build it yourself; it takes a few minutes. +Download a build from the [releases page](https://git.lat/kibi/mumh5/releases): + +| System | File | +|---|---| +| Windows | `mumh5--win-x64.exe` (installer; not signed yet, so Windows SmartScreen warns once) | +| Linux, any distribution | `mumh5--linux-x86_64.AppImage` (make it executable, then run it) | +| Debian, Ubuntu | `mumh5--linux-amd64.deb` | +| Linux, portable | `mumh5--linux-x64.tar.gz` | + +There is no macOS build yet; build it yourself on a Mac (below). + +### Running from source You need [Node.js](https://nodejs.org/) 22 or newer and git. @@ -132,7 +143,7 @@ npm run dist:win # NSIS installer npm run dist:mac # .dmg ``` -Installers are written to `release/`. Build each platform on that platform for the best results. +Installers are written to `release/`. The Windows installer also builds on Linux with Wine installed; the macOS one needs a Mac. Pushing a version tag (`git tag v0.1.0 && git push origin v0.1.0`) makes the Gitea workflow in `.gitea/workflows/release.yml` build the Linux and Windows files and attach them to a release. --- diff --git a/build/icon.png b/build/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..fa5ef813492702c6e4dce78ada80604b0aa1be97 GIT binary patch literal 15479 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 T+*}Hj$Qe9c{an^LB{Ts54@#u3 literal 0 HcmV?d00001 diff --git a/build/icon.svg b/build/icon.svg new file mode 100644 index 0000000..cb3707d --- /dev/null +++ b/build/icon.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/electron/main.ts b/electron/main.ts index 3130eaf..f3aba65 100644 --- a/electron/main.ts +++ b/electron/main.ts @@ -136,6 +136,8 @@ function createWindow() { minHeight: 480, backgroundColor: '#111214', title: 'mumh5', + // Window and taskbar icon on Linux (Windows and macOS take it from the package) + icon: path.join(__dirname, '../dist/icon.png'), autoHideMenuBar: true, webPreferences: { preload: path.join(__dirname, 'preload.cjs'), diff --git a/package.json b/package.json index 51e3272..890a4fd 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "mumh5", "productName": "mumh5", "version": "0.1.0", - "description": "Modern Mumble client with rich chat, file sharing and video", + "description": "A modern Mumble client: Discord-like interface, file sharing, voice and more, for any Mumble server", "license": "MIT", "type": "module", "main": "dist-electron/main.cjs", @@ -26,24 +26,37 @@ "files": [ "dist/**", "dist-electron/**", + "!dist-electron/*.map", "package.json", "LICENSE", "THIRD_PARTY_NOTICES.md" ], "directories": { - "output": "release" + "output": "release", + "buildResources": "build" }, "linux": { "target": [ "AppImage", - "deb" + "deb", + "tar.gz" ], - "category": "Network" + "category": "Network", + "executableName": "mumh5", + "synopsis": "Modern Mumble client", + "desktop": { + "entry": { + "StartupWMClass": "mumh5", + "Keywords": "mumble;voice;chat;voip;" + } + }, + "syncDesktopName": true }, "win": { "target": [ "nsis" - ] + ], + "icon": "build/icon.png" }, "mac": { "target": [ @@ -54,6 +67,22 @@ "NSMicrophoneUsageDescription": "mumh5 uses the microphone for voice chat.", "NSCameraUsageDescription": "mumh5 uses the camera for video chat." } + }, + "icon": "build/icon.png", + "artifactName": "${productName}-${version}-${os}-${arch}.${ext}", + "deb": { + "depends": [ + "libnotify4", + "libxtst6", + "libnss3", + "libasound2 | libasound2t64" + ] + }, + "nsis": { + "oneClick": false, + "allowToChangeInstallationDirectory": true, + "perMachine": false, + "shortcutName": "mumh5" } }, "devDependencies": { @@ -81,9 +110,14 @@ "esbuild@0.28.2": true, "electron-winstaller": false }, - "author": "Kibi Kelburton", + "author": { + "name": "Kibi Kelburton", + "email": "git@f0ck.it" + }, "repository": { "type": "git", "url": "gitea@git.lat:kibi/mumh5.git" - } + }, + "homepage": "https://git.lat/kibi/mumh5", + "desktopName": "mumh5.desktop" } diff --git a/public/icon.png b/public/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..5b7f54d95ce6f1c3821f4e824eaa4a2f025d7412 GIT binary patch literal 3396 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 1100 ? 'wide' : width >= 760 ? 'medium' : 'narrow'); + // Arrangement (Appearance setting): side is the default, classic puts the channel list right + // of the chat, stacked above it. Phones always use drawers. + const arrangement = $derived(layout === 'narrow' ? 'side' : store.settings.arrangement ?? 'side'); + // The member panel sits inline only in the side arrangement on wide windows, otherwise it overlays + const panelInline = $derived(layout === 'wide' && arrangement === 'side'); + let treeHeight = $state(Math.max(120, Number((() => { try { return localStorage.getItem('mumh5.treeHeight'); } catch { return null; } })()) || 280)); + let navOpen = $state(false); let editing = $state<{ server: SavedServer | null } | null>(null); @@ -35,12 +43,13 @@ else delete document.documentElement.dataset.theme; }); - // The panel starts open on wide layouts only + // The panel starts open only where it sits inline let lastLayout = ''; $effect(() => { - if (layout === lastLayout) return; - ui.panelOpen = layout === 'wide'; - lastLayout = layout; + const key = `${layout}/${arrangement}`; + if (key === lastLayout) return; + ui.panelOpen = panelInline; + lastLayout = key; }); // On phones one drawer at a time $effect(() => { if (layout === 'narrow' && ui.panelOpen) navOpen = false; }); @@ -53,26 +62,48 @@ const closeOverlays = () => { navOpen = false; - if (layout !== 'wide') ui.panelOpen = false; + if (!panelInline) ui.panelOpen = false; }; -
- {#if layout !== 'narrow' || navOpen} -