diff --git a/packages/desktop/build/icon.icns b/packages/desktop/build/icon.icns new file mode 100644 index 00000000..7fecb3db Binary files /dev/null and b/packages/desktop/build/icon.icns differ diff --git a/packages/desktop/build/icon.png b/packages/desktop/build/icon.png new file mode 100644 index 00000000..8b6aaccc Binary files /dev/null and b/packages/desktop/build/icon.png differ diff --git a/packages/desktop/build/icons/1024x1024.png b/packages/desktop/build/icons/1024x1024.png new file mode 100644 index 00000000..8b6aaccc Binary files /dev/null and b/packages/desktop/build/icons/1024x1024.png differ diff --git a/packages/desktop/build/icons/128x128.png b/packages/desktop/build/icons/128x128.png new file mode 100644 index 00000000..d50894a6 Binary files /dev/null and b/packages/desktop/build/icons/128x128.png differ diff --git a/packages/desktop/build/icons/16x16.png b/packages/desktop/build/icons/16x16.png new file mode 100644 index 00000000..25fc04d0 Binary files /dev/null and b/packages/desktop/build/icons/16x16.png differ diff --git a/packages/desktop/build/icons/256x256.png b/packages/desktop/build/icons/256x256.png new file mode 100644 index 00000000..2f44c4b0 Binary files /dev/null and b/packages/desktop/build/icons/256x256.png differ diff --git a/packages/desktop/build/icons/32x32.png b/packages/desktop/build/icons/32x32.png new file mode 100644 index 00000000..09fd1de4 Binary files /dev/null and b/packages/desktop/build/icons/32x32.png differ diff --git a/packages/desktop/build/icons/48x48.png b/packages/desktop/build/icons/48x48.png new file mode 100644 index 00000000..415bb6fd Binary files /dev/null and b/packages/desktop/build/icons/48x48.png differ diff --git a/packages/desktop/build/icons/512x512.png b/packages/desktop/build/icons/512x512.png new file mode 100644 index 00000000..0667a4a2 Binary files /dev/null and b/packages/desktop/build/icons/512x512.png differ diff --git a/packages/desktop/build/icons/64x64.png b/packages/desktop/build/icons/64x64.png new file mode 100644 index 00000000..a556cdee Binary files /dev/null and b/packages/desktop/build/icons/64x64.png differ diff --git a/packages/desktop/electron-builder.yml b/packages/desktop/electron-builder.yml index ed452813..80482fc2 100644 --- a/packages/desktop/electron-builder.yml +++ b/packages/desktop/electron-builder.yml @@ -1,5 +1,6 @@ appId: com.backspace.desktop productName: Backspace +artifactName: "${productName}-${version}-${arch}.${ext}" directories: output: dist-electron files: diff --git a/packages/desktop/package.json b/packages/desktop/package.json index 8b134060..4ba83b67 100644 --- a/packages/desktop/package.json +++ b/packages/desktop/package.json @@ -2,6 +2,12 @@ "name": "@backspace/desktop", "version": "1.0.0", "private": true, + "description": "Backspace — a self-hosted, open-source chat platform", + "author": { + "name": "youruser", + "email": "backspace@backspace.chat" + }, + "homepage": "https://github.com/youruser/backspace", "main": "dist/main.js", "scripts": { "build:ts": "tsc", diff --git a/packages/desktop/src/main.ts b/packages/desktop/src/main.ts index 3dcc37dd..bd528d61 100644 --- a/packages/desktop/src/main.ts +++ b/packages/desktop/src/main.ts @@ -186,7 +186,14 @@ function createWindow(): void { minHeight: 500, title: 'Backspace', icon: path.join(__dirname, '..', 'build', 'icon.png'), - titleBarStyle: process.platform === 'darwin' ? 'hiddenInset' : 'default', + titleBarStyle: process.platform === 'darwin' ? 'hiddenInset' : 'hidden', + ...(process.platform !== 'darwin' ? { + titleBarOverlay: { + color: '#0b0b10', + symbolColor: '#d8d8de', + height: 32, + }, + } : {}), backgroundColor: '#313338', show: false, webPreferences: { @@ -561,6 +568,23 @@ if (!gotTheLock) { }, ]); Menu.setApplicationMenu(appMenu); + } else { + // Win/Linux: frameless window has no menu bar, but we still need an + // application menu so keyboard accelerators (Ctrl+C/V/X/Z/A) work. + Menu.setApplicationMenu(Menu.buildFromTemplate([ + { + label: 'Edit', + submenu: [ + { role: 'undo' }, + { role: 'redo' }, + { type: 'separator' }, + { role: 'cut' }, + { role: 'copy' }, + { role: 'paste' }, + { role: 'selectAll' }, + ], + }, + ])); } // Purge ALL stale caches so Electron always loads fresh code on launch diff --git a/packages/web/src/App.tsx b/packages/web/src/App.tsx index 06808c8e..6e87adc5 100644 --- a/packages/web/src/App.tsx +++ b/packages/web/src/App.tsx @@ -7,7 +7,7 @@ import { JoinPage } from './components/JoinPage'; import { SwAutoUpdate } from './components/ui/SwUpdatePrompt'; import { ScreenSharePicker } from './components/voice/ScreenSharePicker'; import { useAuthStore } from './stores/authStore'; -import { isElectronMac } from './platform/platform'; +import { isElectron } from './platform/platform'; function ProtectedRoute({ children }: { children: React.ReactNode }) { const token = useAuthStore((s) => s.token); @@ -29,13 +29,14 @@ function AuthRedirect({ children }: { children: React.ReactNode }) { } export function App() { - const showTitleBar = isElectronMac(); + const showTitleBar = isElectron(); return (
- {showTitleBar && ( + {showTitleBar && <>
- )} +
+ }
diff --git a/packages/web/src/components/layout/SpaceSidebar.tsx b/packages/web/src/components/layout/SpaceSidebar.tsx index 23db3fd2..7e3be1c3 100644 --- a/packages/web/src/components/layout/SpaceSidebar.tsx +++ b/packages/web/src/components/layout/SpaceSidebar.tsx @@ -13,7 +13,7 @@ import { TransferOwnershipModal } from '../modals/TransferOwnershipModal'; import type { SpaceLayoutItem, SpaceFolder } from '@backspace/shared'; import { getSpaceGradient, HOME_GRADIENT } from '../../utils/gradients'; -import { isElectronMac } from '../../platform/platform'; +import { isElectron } from '../../platform/platform'; import { useFloatingPosition } from '../../hooks/useFloatingPosition'; // ─── Resolved layout types ───────────────────────────────────────────────── @@ -79,7 +79,7 @@ function SidebarItem({ id, name, icon, avatarColor, active, onClick, onContextMe } if (type === 'dm') { - return { background: HOME_GRADIENT.gradient }; + return undefined; } // Space type — if it has a custom icon image, no gradient needed @@ -110,7 +110,7 @@ function SidebarItem({ id, name, icon, avatarColor, active, onClick, onContextMe const buttonContent = (