initial commit
This commit is contained in:
38
README.md
Normal file
38
README.md
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
# Bumble Electron
|
||||||
|
|
||||||
|
A very small Electron shell that wraps the Bumble web app so you can keep it next to the rest of your desktop messengers.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
- Loads the official Bumble web experience at `https://bumble.com/get-started` inside a dedicated window.
|
||||||
|
- Blocks unexpected navigation (drag-and-drop or pop-out windows open in your default browser).
|
||||||
|
- Single-instance enforcement so app links/notifications focus the already running window.
|
||||||
|
- Pre-configured permissions for microphone, camera, geolocation, and notifications to match the needs of voice/video calls.
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
1. Install dependencies once:
|
||||||
|
```bash
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
2. Launch the desktop app:
|
||||||
|
```bash
|
||||||
|
npm start
|
||||||
|
```
|
||||||
|
3. Log in with your Bumble account right from the window that appears.
|
||||||
|
|
||||||
|
The project uses Electron only; no build step is required. If you want the window back after closing (macOS), use the dock icon or rerun `npm start`.
|
||||||
|
|
||||||
|
### Window behavior
|
||||||
|
- Clicking the close button now just minimizes the window so Bumble keeps running in the background.
|
||||||
|
- Use `Cmd+Q` (macOS) or `Ctrl+Q` (Windows/Linux) to quit the app completely.
|
||||||
|
|
||||||
|
## Build a Desktop Binary
|
||||||
|
Electron Builder is preconfigured for macOS, Windows, and Linux. To create unsigned binaries for your current platform:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
Artifacts land in `dist/`. When building on macOS without a valid signing identity (or if you need to skip signing), set `CSC_IDENTITY_AUTO_DISCOVERY=false` before running the build.
|
||||||
|
|
||||||
|
## Packaging Notes
|
||||||
|
The default build outputs (mac `.app`, Windows installer via NSIS, Linux AppImage/Deb) are defined in `package.json#build`. Adjust that section if you need different targets or want to point at alternative icons/resources.
|
||||||
BIN
bumble_icon_512.png
Normal file
BIN
bumble_icon_512.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
42
package.json
Normal file
42
package.json
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "bumble-electron",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Desktop Electron shell for Bumble Web.",
|
||||||
|
"main": "src/main.js",
|
||||||
|
"scripts": {
|
||||||
|
"start": "electron .",
|
||||||
|
"dev": "electron .",
|
||||||
|
"build": "electron-builder"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"electron",
|
||||||
|
"bumble",
|
||||||
|
"desktop"
|
||||||
|
],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"build": {
|
||||||
|
"appId": "com.victorstools.bumble",
|
||||||
|
"productName": "Bumble Desktop",
|
||||||
|
"mac": {
|
||||||
|
"category": "public.app-category.social-networking",
|
||||||
|
"icon": "bumble_icon_512.png"
|
||||||
|
},
|
||||||
|
"win": {
|
||||||
|
"target": "nsis",
|
||||||
|
"icon": "bumble_icon_512.png"
|
||||||
|
},
|
||||||
|
"linux": {
|
||||||
|
"target": [
|
||||||
|
"AppImage",
|
||||||
|
"deb"
|
||||||
|
],
|
||||||
|
"category": "Network",
|
||||||
|
"icon": "bumble_icon_512.png"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"electron": "^39.1.1",
|
||||||
|
"electron-builder": "^26.0.12"
|
||||||
|
}
|
||||||
|
}
|
||||||
138
src/main.js
Normal file
138
src/main.js
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
const {
|
||||||
|
app,
|
||||||
|
BrowserWindow,
|
||||||
|
Menu,
|
||||||
|
shell,
|
||||||
|
session,
|
||||||
|
nativeTheme,
|
||||||
|
globalShortcut
|
||||||
|
} = require('electron');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const BUMBLE_URL = 'https://bumble.com/get-started';
|
||||||
|
const SINGLE_INSTANCE_LOCK = app.requestSingleInstanceLock();
|
||||||
|
const ALLOWED_PERMISSIONS = new Set(['media', 'geolocation', 'notifications']);
|
||||||
|
const ICON_PATH = path.join(__dirname, '..', 'bumble_icon_512.png');
|
||||||
|
|
||||||
|
let mainWindow;
|
||||||
|
let isQuitting = false;
|
||||||
|
|
||||||
|
app.setAppUserModelId('com.victorstools.bumble');
|
||||||
|
|
||||||
|
if (!SINGLE_INSTANCE_LOCK) {
|
||||||
|
app.quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
const desktopUserAgent = `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${process.versions.chrome} Safari/537.36`;
|
||||||
|
|
||||||
|
const configureSession = () => {
|
||||||
|
const defaultSession = session.defaultSession;
|
||||||
|
if (!defaultSession) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultSession.setPermissionRequestHandler((_, permission, callback) => {
|
||||||
|
callback(ALLOWED_PERMISSIONS.has(permission));
|
||||||
|
});
|
||||||
|
|
||||||
|
defaultSession.setUserAgent(desktopUserAgent);
|
||||||
|
};
|
||||||
|
|
||||||
|
const createWindow = () => {
|
||||||
|
if (mainWindow) {
|
||||||
|
return mainWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
mainWindow = new BrowserWindow({
|
||||||
|
width: 1200,
|
||||||
|
height: 800,
|
||||||
|
minWidth: 900,
|
||||||
|
minHeight: 600,
|
||||||
|
title: 'Bumble',
|
||||||
|
backgroundColor: nativeTheme.shouldUseDarkColors ? '#16161a' : '#ffffff',
|
||||||
|
icon: ICON_PATH,
|
||||||
|
autoHideMenuBar: true,
|
||||||
|
webPreferences: {
|
||||||
|
preload: path.join(__dirname, 'preload.js'),
|
||||||
|
contextIsolation: true,
|
||||||
|
nodeIntegration: false,
|
||||||
|
spellcheck: true,
|
||||||
|
sandbox: false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
mainWindow.loadURL(BUMBLE_URL, { userAgent: desktopUserAgent });
|
||||||
|
|
||||||
|
mainWindow.webContents.setWindowOpenHandler(({ url }) => {
|
||||||
|
shell.openExternal(url);
|
||||||
|
return { action: 'deny' };
|
||||||
|
});
|
||||||
|
|
||||||
|
mainWindow.webContents.on('will-navigate', (event, url) => {
|
||||||
|
if (!url.startsWith('https://') && !url.startsWith('http://')) {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
mainWindow.on('close', event => {
|
||||||
|
if (!isQuitting) {
|
||||||
|
event.preventDefault();
|
||||||
|
mainWindow.minimize();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
mainWindow.on('closed', () => {
|
||||||
|
mainWindow = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
return mainWindow;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (SINGLE_INSTANCE_LOCK) {
|
||||||
|
app.on('second-instance', () => {
|
||||||
|
if (mainWindow) {
|
||||||
|
if (mainWindow.isMinimized()) {
|
||||||
|
mainWindow.restore();
|
||||||
|
}
|
||||||
|
mainWindow.show();
|
||||||
|
mainWindow.focus();
|
||||||
|
} else {
|
||||||
|
createWindow();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
app.on('before-quit', () => {
|
||||||
|
isQuitting = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
app.whenReady().then(() => {
|
||||||
|
Menu.setApplicationMenu(null);
|
||||||
|
configureSession();
|
||||||
|
createWindow();
|
||||||
|
globalShortcut.register('CommandOrControl+Q', () => {
|
||||||
|
isQuitting = true;
|
||||||
|
app.quit();
|
||||||
|
});
|
||||||
|
|
||||||
|
app.on('activate', () => {
|
||||||
|
if (mainWindow) {
|
||||||
|
if (mainWindow.isMinimized()) {
|
||||||
|
mainWindow.restore();
|
||||||
|
}
|
||||||
|
mainWindow.show();
|
||||||
|
} else {
|
||||||
|
createWindow();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
app.on('window-all-closed', () => {
|
||||||
|
if (process.platform !== 'darwin') {
|
||||||
|
app.quit();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.on('will-quit', () => {
|
||||||
|
globalShortcut.unregisterAll();
|
||||||
|
});
|
||||||
19
src/preload.js
Normal file
19
src/preload.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
const { contextBridge } = require('electron');
|
||||||
|
|
||||||
|
// Prevent files from being dropped into the Bumble webview, which would otherwise
|
||||||
|
// trigger navigations away from the Bumble UI.
|
||||||
|
window.addEventListener('dragover', event => {
|
||||||
|
event.preventDefault();
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener('drop', event => {
|
||||||
|
event.preventDefault();
|
||||||
|
});
|
||||||
|
|
||||||
|
contextBridge.exposeInMainWorld('bumbleDesktop', {
|
||||||
|
platform: process.platform,
|
||||||
|
versions: {
|
||||||
|
chrome: process.versions.chrome,
|
||||||
|
electron: process.versions.electron
|
||||||
|
}
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user