Skip to content

Commit

Permalink
Merge pull request #48 from chrisknepper/feature/add-context-menu-and…
Browse files Browse the repository at this point in the history
…-changelog

-Add right-click/context menu a la normal browser would have (Fixes #38)
  • Loading branch information
chrisknepper authored Jul 14, 2018
2 parents 621a824 + 90ae8e1 commit dbd7182
Show file tree
Hide file tree
Showing 8 changed files with 203 additions and 62 deletions.
98 changes: 98 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
## [0.4.0] - 2018-07-14
### Added
- Right-click context menu with support for cut/copy/paste/undo/redo/save image/save video
- Builds for pacman package manager (used by Arch Linux and related distros)
- Changelog (with shortcut to changelog in Help menu)

### Changed
- Update README.md
- On launch, open dev tools for the webview when in dev mode

### Fixed
- App icon not showing or showing sporadically on Linux

### Removed
- Some dead code/comments

## [0.3.0] - 2018-07-08
### Added
- Tray icon support for macOS and Linux
- Show/hide toggle to tray context menu
- File menu with items to manually check for updates and quit the app
- Standard Window menu provided by electron (with proper minimize/hide items and keyboard shortcuts)
- One-time notification about minimizing to tray on Windows
- Build scripts to only build instead of building and attempting to publish a release

### Changed
- Minimize/close behavior on Windows and Linux (minimizing now minimizes, closing now minimizes to tray)
- Refactor menu code

### Fixed
- Command+H app hiding behavior on macOS (now defocuses app when hiding window)

## [0.2.0] - 2018-07-05
### Added
- Setting to auto-hide menu bar (and toggle its appearance via the standard Alt+H shortcut) on Windows and Linux
- electron-settings dependency for managing the above and future user settings
- Screenshots of Windows tray and macOS dock functionality

### Changed
- Update README.md

### Removed
- "Hello World" code and unit/e2e tests from boilerplate

## [0.1.0] - 2018-06-27
### Added
- Notification count badge in dock on macOS (clears on window focus/app.activate)
- Tray icon and minimizing to tray for Windows
- Command+H shortcut to hide app on macOS

### Changed
- Closing window on macOS now doesn't quit app (expected UX on macOS)
- Prevent multiple instances of app being able to launch (for example, when minimized to tray on Windows without pinning to taskbar, then clicking a shortcut from the Start menu)
- Update README.md

## [0.0.5] - 2018-06-26
### Changed
- Update README.md
- Update shape of chat bubble in icon
- Use different combination of scripts to generate icons

### Fixed
- Corrupt icons in Windows Taskbar and macOS Spotlight

## [0.0.4] - 2018-06-24
### Changed
- README.md even more complete

### Fixed
- Hyperlinks in text messages now open in system default browser when clicked

## [0.0.3] - 2018-06-22
### Changed
- Nothing besides the version number, just created this version to test auto-update functionality

## [0.0.2] - 2018-06-22
### Added
- Signed app binary for macOS
- Notifications on Windows
- Builds for various Linux distros/package managers
- A real icon
- Auto-update mechanism via electron-updater
- TODOs

### Changed
- README.md more complete
- package.json more complete
- Values and code elements from boilerplate updates
- Automatically pop-up dev tools in dev mode
- Generate icons via a script

## 0.0.1 - 2018-06-21
### Added
- Project files (initial release)

### Changed
- It works! (I think hope)
- No Linux binary, no signing certs for Mac/Windows, no actual icon...but it's a start.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Based on:
Head over to the [latest releases](https://github.com/chrisknepper/android-messages-desktop/releases/latest) page!
* For Mac, choose the **dmg**
* For Windows, choose the **exe**
* For Linux, choose either the **deb**, the **snap**, or the **AppImage**
* For Linux, choose either the **deb**, the **snap**, the **pacman**, or the **AppImage**

**Important note:** The Windows app binary isn't signed. This doesn't seem to be a big problem, but please report any issues you run into on Windows that may be related to signing.

Expand All @@ -40,7 +40,7 @@ Head over to the [latest releases](https://github.com/chrisknepper/android-messa
- [x] Make sure it actually works (definitely works as of v0.1.0, done via [8068ed2](../../commit/8068ed2))
- [x] Release signed binaries for macOS (binaries are signed as of v0.0.2, done via [8492023](../../commit/8492023))
- [x] Make an icon (done via [df625ba](../../commit/df625ba))
- [ ] Remove left-over code from electron-boilerplate
- [x] Remove left-over code from electron-boilerplate (done via [4e7638a](../../commit/4e7638a))
- [ ] Correct tests
- [x] Release packages for Linux (done via [41ed205](../../commit/41ed205))
- [x] Handling updates (done via [625bf6d](../../commit/625bf6d))
Expand Down
2 changes: 1 addition & 1 deletion app/app.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<body>
<div id="app">
<!-- <webview id="androidMessagesWebview" src="https://davidwalsh.name/demo/notifications-api.php" autosize></webview> -->
<webview id="androidMessagesWebview" src="https://messages.android.com/" autosize></webview>
<webview id="androidMessagesWebview" src="https://messages.android.com/" autosize preload="../src/helpers/webview.js"></webview>
<div id="loader"></div>
</div>
<script src="app.js"></script>
Expand Down
8 changes: 4 additions & 4 deletions src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ import path from 'path';

import './stylesheets/main.css';

import './helpers/context_menu.js';
import './helpers/external_links.js';

import { remote, shell } from 'electron';
import url from 'url';
import jetpack from 'fs-jetpack';
import { IS_MAC, IS_LINUX } from './constants';
import { IS_MAC, IS_DEV } from './constants';

const state = {
loaded: false,
Expand All @@ -18,8 +17,6 @@ const state = {
const app = remote.app;
const appDir = jetpack.cwd(app.getAppPath());

// TODO: Insert or update webview here instead of in the HTML file to make testing (swapping URLs) easier

androidMessagesWebview.addEventListener('did-start-loading', () => {

// Intercept request for notifications and accept it
Expand Down Expand Up @@ -68,6 +65,9 @@ androidMessagesWebview.addEventListener('did-stop-loading', () => { // coinciden
if (!state.loaded) {
state.loaded = true;
loader.classList.add('hidden');
if (IS_DEV) {
androidMessagesWebview.getWebContents().openDevTools();
}
}

});
Expand Down
6 changes: 0 additions & 6 deletions src/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,6 @@ if (isSecondInstance) {

autoUpdater.checkForUpdatesAndNotify();

// mainWindow = createWindow('main', {
// width: 1100,
// height: 800,
// autoHideMenuBar: settings.get("autoHideMenuPref")
// });

const mainWindowOptions = {
width: 1100,
height: 800,
Expand Down
136 changes: 87 additions & 49 deletions src/helpers/context_menu.js
Original file line number Diff line number Diff line change
@@ -1,59 +1,97 @@
// This gives you default context menu (cut, copy, paste)
// in all input fields and textareas across your app.
// Provide context menus (copy, paste, save image, etc...) for right-click interaction.
// Must not contain certain newer JS syntaxes to allow use inside a webview.

import { remote } from "electron";
const remote = require('electron').remote;

const Menu = remote.Menu;
const MenuItem = remote.MenuItem;

const isAnyTextSelected = () => {
return window.getSelection().toString() !== "";
};

const cut = new MenuItem({
label: "Cut",
click: () => {
document.execCommand("cut");
}
});

const copy = new MenuItem({
label: "Copy",
click: () => {
document.execCommand("copy");
const standardMenuTemplate = [
{
label: 'Copy',
role: 'copy',
},
{
type: 'separator',
},
{
label: 'Select All',
role: 'selectall',
}
});
];

const paste = new MenuItem({
label: "Paste",
click: () => {
document.execCommand("paste");
const textMenuTemplate = [
{
label: 'Undo',
role: 'undo',
},
{
label: 'Redo',
role: 'redo',
},
{
type: 'separator',
},
{
label: 'Cut',
role: 'cut',
},
{
label: 'Copy',
role: 'copy',
},
{
label: 'Paste',
role: 'paste',
},
{
type: 'separator',
},
{
label: 'Select All',
role: 'selectall',
}
});
];

const normalMenu = new Menu();
normalMenu.append(copy);
const standardInputMenu = Menu.buildFromTemplate(standardMenuTemplate);
const textInputMenu = Menu.buildFromTemplate(textMenuTemplate);

const textEditingMenu = new Menu();
textEditingMenu.append(cut);
textEditingMenu.append(copy);
textEditingMenu.append(paste);
const popupContextMenu = (event) => {
switch (event.target.nodeName) {
case 'VIDEO':
case 'IMG':
if (event.target.src && event.target.src.length) {
let mediaType = event.target.nodeName === 'IMG' ? 'Image' : 'Video';
const mediaInputMenu = Menu.buildFromTemplate([{
label: `Save ${mediaType} As...`,
click: () => {
// This call *would* do this in one line, but is only a thing in IE (???)
// document.execCommand('SaveAs', true, event.target.src);
const link = document.createElement('a');
link.href = event.target.src;
// Leaving the URL root results in the file extension being truncated.
// The resulting filename from this also appears to be consistent with
// saving the image via dragging or the Chrome context menu...winning!
link.download = event.target.src.replace('blob:https://messages.android.com/', '');
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
}]);
mediaInputMenu.popup({
window: remote.getCurrentWindow(),
callback: () => {
mediaInputMenu = null; // Unsure if memory would leak without this (Clean up, clean up, everybody do your share)
}
});
}
break;
default:
if (event.target.isContentEditable) {
textInputMenu.popup(remote.getCurrentWindow());
} else { // Omit options pertaining to input fields if this isn't one
standardInputMenu.popup(remote.getCurrentWindow());
}
}
};

document.addEventListener(
"contextmenu",
event => {
switch (event.target.nodeName) {
case "TEXTAREA":
case "INPUT":
event.preventDefault();
textEditingMenu.popup(remote.getCurrentWindow());
break;
default:
if (isAnyTextSelected()) {
event.preventDefault();
normalMenu.popup(remote.getCurrentWindow());
}
}
},
false
);
module.exports = popupContextMenu;
7 changes: 7 additions & 0 deletions src/helpers/webview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// This script is injected into the webview.
// Newer ES6 features (import/export syntax etc...) are not allowed here nor in any JS which this imports.

const popupContextMenu = require('./context_menu.js');

// Electron (or the build of Chromium it uses?) does not seem to have any default right-click menu, this adds our own.
window.addEventListener('contextmenu', popupContextMenu);
4 changes: 4 additions & 0 deletions src/menu/help_menu_template.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ export const helpMenuTemplate = {
{
label: 'Learn More',
click: () => shell.openExternal('https://github.com/chrisknepper/android-messages-desktop/')
},
{
label: 'Changelog',
click: () => shell.openExternal('https://github.com/chrisknepper/android-messages-desktop/blob/master/CHANGELOG.md')
}
]
};
Expand Down

0 comments on commit dbd7182

Please sign in to comment.