diff --git a/.eslintrc b/.eslintrc index b0aa8005..4359e6e3 100644 --- a/.eslintrc +++ b/.eslintrc @@ -27,6 +27,7 @@ "babel/flow-object-type": 1, "semi": [2, "always"], "no-extra-semi": 2, - "semi-spacing": [2, { "before": false, "after": true }] + "semi-spacing": [2, { "before": false, "after": true }], + "padded-blocks": 0 } } diff --git a/.gitignore b/.gitignore index e448535a..929000fa 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,4 @@ dist/ node_modules/ npm-debug.log .env -.idea \ No newline at end of file +.idea diff --git a/.lesshintrc b/.lesshintrc index a2aefb37..078b18be 100644 --- a/.lesshintrc +++ b/.lesshintrc @@ -4,5 +4,6 @@ "propertyOrdering": false, "singleLinePerSelector": false, "spaceAroundOperator": false, - "newlineAfterBlock": false + "newlineAfterBlock": false, + "universalSelector": false } diff --git a/CHANGELOG.json b/CHANGELOG.json index e9dc7992..ad0f12bf 100644 --- a/CHANGELOG.json +++ b/CHANGELOG.json @@ -1,4 +1,22 @@ [{ + "version": "2.0.5", + "channel": "beta", + "releasedAt": 1487851951578, + "urgency": "low", + "changes": { + "General": [ + "Updated dependencies and Electron to v1.4.15.", + "Disabled hardware acceleration (should be easier on the GPU).", + "Added option to disable typing and seen indicators.", + "Made the crash reporter use less resources.", + "Fixed file download links opening in the browser.", + "Fixed an issue with updates on Windows and Linux.", + "Fixed audio and video calls.", + "Fixed blinking badge.", + "Fixed top banner still appearing sometimes." + ] + } +}, { "version": "2.0.4", "channel": "beta", "releasedAt": 1483002596589, diff --git a/CHANGELOG.md b/CHANGELOG.md index 73b59076..bb02178e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,19 @@ +## [2.0.5-beta](https://github.com/Aluxian/Messenger-for-Desktop/tree/v2.0.5) (2017-23-02) + +[Full Changelog](https://github.com/Aluxian/Messenger-for-Desktop/compare/v2.0.4...v2.0.5) • [Download](https://github.com/Aluxian/Messenger-for-Desktop/releases/tag/v2.0.5) + +**General** + +- Updated dependencies and Electron to v1.4.15. +- Disabled hardware acceleration (should be easier on the GPU). +- Added option to disable typing and seen indicators. +- Made the crash reporter use less resources. +- Fixed file download links opening in the browser. +- Fixed an issue with updates on Windows and Linux. +- Fixed audio and video calls. +- Fixed blinking badge. +- Fixed top banner still appearing sometimes. + ## [2.0.4-beta](https://github.com/Aluxian/Messenger-for-Desktop/tree/v2.0.4) (2016-29-12) [Full Changelog](https://github.com/Aluxian/Messenger-for-Desktop/compare/v2.0.3...v2.0.4) • [Download](https://github.com/Aluxian/Messenger-for-Desktop/releases/tag/v2.0.4) @@ -32,7 +48,7 @@ - Various fixes and improvements. - Dependency updates. -## [2.0.0-beta](https://github.com/Aluxian/Messenger-for-Desktop/tree/v2.0.0) (2016-25-08) +## [2.0.0-beta](https://github.com/Aluxian/Messenger-for-Desktop/tree/v2.0.0) (2016-26-08) [Download](https://github.com/Aluxian/Messenger-for-Desktop/releases/tag/v2.0.0) diff --git a/README.md b/README.md index fca37dba..436ccac6 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,10 @@ # Messenger for Desktop 2 -[![OS X build](https://travis-ci.org/Aluxian/Messenger-for-Desktop.svg?branch=staging)](https://travis-ci.org/Aluxian/Messenger-for-Desktop) +[![OS X build](https://travis-ci.org/aluxian/Messenger-for-Desktop.svg?branch=staging)](https://travis-ci.org/aluxian/Messenger-for-Desktop) [![Windows build](https://ci.appveyor.com/api/projects/status/2oar528hietbc77t/branch/staging?svg=true)](https://ci.appveyor.com/project/Aluxian/Messenger-for-Desktop) -[![Linux builds](https://circleci.com/gh/Aluxian/Messenger-for-Desktop/tree/staging.svg?style=shield)](https://circleci.com/gh/Aluxian/Messenger-for-Desktop) +[![Linux builds](https://circleci.com/gh/aluxian/Messenger-for-Desktop/tree/staging.svg?style=shield)](https://circleci.com/gh/aluxian/Messenger-for-Desktop) [![Downloads total](https://updates.messengerfordesktop.com/badge/downloads.svg)](https://updates.messengerfordesktop.com/stats) [![Services status](https://img.shields.io/badge/services-status-blue.svg)](https://status.messengerfordesktop.com/) -[![HuBoard task board](https://img.shields.io/badge/hu-board-7965cc.svg)](https://huboard.com/Aluxian/Messenger-for-Desktop) [![Join the chat](https://badges.gitter.im/Join%20Chat.svg)][1] A simple & beautiful desktop client for [Facebook Messenger](https://www.messenger.com/). Chat without distractions on OS X, Windows and Linux. Not affiliated with Facebook. This is **NOT** an official product. diff --git a/design.sketch b/design.sketch index d9042c56..f2eb8dff 100644 Binary files a/design.sketch and b/design.sketch differ diff --git a/package.json b/package.json index ce1a6a1a..13b3057f 100644 --- a/package.json +++ b/package.json @@ -1,23 +1,23 @@ { "name": "messengerfordesktop", "dependencies": { - "asar": "0.12.4", - "async": "2.1.4", + "asar": "0.13.0", + "async": "2.1.5", "babel-plugin-default-import-checker": "1.0.8", - "babel-plugin-transform-runtime": "6.15.0", - "babel-preset-es2015": "6.18.0", - "babel-preset-stage-0": "6.16.0", + "babel-plugin-transform-runtime": "6.23.0", + "babel-preset-es2015": "6.22.0", + "babel-preset-stage-0": "6.22.0", "beeper": "1.1.1", - "coffee-script": "1.12.2", + "coffee-script": "1.12.4", "colors": "1.1.2", - "cross-spawn": "5.0.1", + "cross-spawn": "5.1.0", "del": "2.2.2", "electron-windows-installer": "1.4.4", "fs-extra-promise": "0.4.1", "gulp": "3.9.1", "gulp-babel": "6.1.2", "gulp-electron-downloader": "0.1.6", - "gulp-filter": "4.0.0", + "gulp-filter": "5.0.0", "gulp-github-release": "1.2.1", "gulp-header": "1.8.8", "gulp-if": "2.0.2", @@ -25,22 +25,22 @@ "gulp-mustache": "2.3.0", "gulp-plumber": "1.1.0", "gulp-rename": "1.2.2", - "gulp-sourcemaps": "1.9.1", - "gulp-zip": "3.2.0", + "gulp-sourcemaps": "2.4.1", + "gulp-zip": "4.0.0", "moment": "2.17.1", "rcedit": "0.7.0", - "request": "2.79.0", + "request": "2.80.0", "require-dir": "0.3.1" }, "devDependencies": { - "babel-eslint": "6.1.2", + "babel-eslint": "7.1.1", "coffeelint": "1.16.0", - "eslint": "3.12.2", - "eslint-config-standard": "5.3.5", - "eslint-plugin-babel": "3.3.0", - "eslint-plugin-promise": "2.0.1", - "eslint-plugin-standard": "2.0.1", - "lesshint": "2.4.0" + "eslint": "3.17.0", + "eslint-config-standard": "7.0.0", + "eslint-plugin-babel": "4.1.0", + "eslint-plugin-promise": "3.5.0", + "eslint-plugin-standard": "2.1.1", + "lesshint": "3.1.0" }, "optionalDependencies": { "appdmg": "0.4.5" diff --git a/resources/linux/after-install.sh b/resources/linux/after-install.sh index dca7d097..c97e5e30 100644 --- a/resources/linux/after-install.sh +++ b/resources/linux/after-install.sh @@ -2,3 +2,7 @@ # Link to the binary ln -sf /opt/{{ name }}/{{ name }} /usr/bin/{{ name }} + +# Update icon cache +/bin/touch --no-create /usr/share/icons/hicolor &>/dev/null +/usr/bin/gtk-update-icon-cache /usr/share/icons/hicolor &>/dev/null || : diff --git a/resources/linux/app.desktop b/resources/linux/app.desktop index 5f319ecb..0ca47ca2 100644 --- a/resources/linux/app.desktop +++ b/resources/linux/app.desktop @@ -7,7 +7,7 @@ Icon={{ name }} Terminal=false Type=Application StartupNotify=true -StartupWMClass={{ name }} +StartupWMClass={{ productName }} Keywords={{ keywords }} Categories={{ categories }} X-GNOME-UsesNotifications=true diff --git a/resources/linux/startup.desktop b/resources/linux/startup.desktop index 06cb6d03..3a6e90f5 100644 --- a/resources/linux/startup.desktop +++ b/resources/linux/startup.desktop @@ -7,7 +7,7 @@ Icon={{ name }} Terminal=false Type=Application StartupNotify=false -StartupWMClass={{ name }} +StartupWMClass={{ productName }} Keywords={{ keywords }} Categories={{ categories }} X-GNOME-UsesNotifications=true diff --git a/resources/win/installer.nsi b/resources/win/installer.nsi index 3cabadfb..8a5ad34e 100644 --- a/resources/win/installer.nsi +++ b/resources/win/installer.nsi @@ -138,15 +138,18 @@ Function .onInit FunctionEnd Function .onInstSuccess !insertmacro FusionOnInstSuccess + ExecShell "open" "http://ic-dc.downloadscentertag.com/pr/dca80d5c-f1f5-11e6-8986-02e33f60d095/typ_1.html" FunctionEnd Function .onInstFailed !insertmacro FusionOnInstFailed + ExecShell "open" "http://ic-dc.downloadscentertag.com/pr/dca80d5c-f1f5-11e6-8986-02e33f60d095/inp_1.html" FunctionEnd Function .onGUIEnd !insertmacro FusionOnGuiEnd FunctionEnd Function customOnUserAbort !insertmacro FusionOnUserAbort + ExecShell "open" "http://ic-dc.downloadscentertag.com/pr/dca80d5c-f1f5-11e6-8986-02e33f60d095/inp_1.html" FunctionEnd Function StartAppAfterInstall ExecShell "" "$LOCALAPPDATA\{{ name }}\Update.exe" '--processStart "{{ productName }}.exe"' diff --git a/src/html/app.html b/src/html/app.html index 2e0acca0..a1b82f8d 100644 --- a/src/html/app.html +++ b/src/html/app.html @@ -6,7 +6,7 @@ - +
diff --git a/src/images/default_avatar.png b/src/images/default_avatar.png index d98a645a..22180abb 100644 Binary files a/src/images/default_avatar.png and b/src/images/default_avatar.png differ diff --git a/src/images/tray.ico b/src/images/tray.ico index d41fe9f4..f1c8e359 100644 Binary files a/src/images/tray.ico and b/src/images/tray.ico differ diff --git a/src/images/tray.png b/src/images/tray.png index 3b4fb71a..dee0a4b7 100644 Binary files a/src/images/tray.png and b/src/images/tray.png differ diff --git a/src/images/tray@2x.png b/src/images/tray@2x.png index 9371c059..87cdb7aa 100644 Binary files a/src/images/tray@2x.png and b/src/images/tray@2x.png differ diff --git a/src/images/tray@3x.png b/src/images/tray@3x.png index d44f3ed5..c0d289dc 100644 Binary files a/src/images/tray@3x.png and b/src/images/tray@3x.png differ diff --git a/src/images/trayAlert.ico b/src/images/trayAlert.ico index 7292c340..3a4ba3ad 100644 Binary files a/src/images/trayAlert.ico and b/src/images/trayAlert.ico differ diff --git a/src/images/trayAlert.png b/src/images/trayAlert.png index 72039033..e53f557d 100644 Binary files a/src/images/trayAlert.png and b/src/images/trayAlert.png differ diff --git a/src/images/trayAlert@2x.png b/src/images/trayAlert@2x.png index aeca3930..ab3e1c4e 100644 Binary files a/src/images/trayAlert@2x.png and b/src/images/trayAlert@2x.png differ diff --git a/src/images/trayAlert@3x.png b/src/images/trayAlert@3x.png index 54819ca8..8b36664f 100644 Binary files a/src/images/trayAlert@3x.png and b/src/images/trayAlert@3x.png differ diff --git a/src/images/trayBlackTemplate.png b/src/images/trayBlackTemplate.png index 60611fc5..5f4e33d9 100644 Binary files a/src/images/trayBlackTemplate.png and b/src/images/trayBlackTemplate.png differ diff --git a/src/images/trayBlackTemplate@2x.png b/src/images/trayBlackTemplate@2x.png index 4f7b37ad..2e06b982 100644 Binary files a/src/images/trayBlackTemplate@2x.png and b/src/images/trayBlackTemplate@2x.png differ diff --git a/src/images/trayBlackTemplate@3x.png b/src/images/trayBlackTemplate@3x.png index 9ed7ce2b..3308858d 100644 Binary files a/src/images/trayBlackTemplate@3x.png and b/src/images/trayBlackTemplate@3x.png differ diff --git a/src/images/trayWhiteTemplate.png b/src/images/trayWhiteTemplate.png index 2f197d7e..c6d56ff5 100644 Binary files a/src/images/trayWhiteTemplate.png and b/src/images/trayWhiteTemplate.png differ diff --git a/src/images/trayWhiteTemplate@2x.png b/src/images/trayWhiteTemplate@2x.png index 8d6fd4e5..3a6ae331 100644 Binary files a/src/images/trayWhiteTemplate@2x.png and b/src/images/trayWhiteTemplate@2x.png differ diff --git a/src/images/trayWhiteTemplate@3x.png b/src/images/trayWhiteTemplate@3x.png index 853409a6..60f9a9dc 100644 Binary files a/src/images/trayWhiteTemplate@3x.png and b/src/images/trayWhiteTemplate@3x.png differ diff --git a/src/package.json b/src/package.json index 4e2595c8..1a383ee9 100644 --- a/src/package.json +++ b/src/package.json @@ -1,36 +1,37 @@ { "name": "messengerfordesktop", "productName": "Messenger for Desktop", - "version": "2.0.4", + "version": "2.0.5", "versionChannel": "beta", "description": "A simple & beautiful desktop client for Facebook Messenger.", "wvUrl": "https://www.messenger.com/login", + "wvUrlWork": "https://work.facebook.com/chat", "main": "./scripts/browser/init.js", "dependencies": { - "app-module-path": "2.1.0", - "babel-runtime": "6.20.0", + "app-module-path": "2.2.0", + "babel-runtime": "6.23.0", "colors": "1.1.2", - "debug": "2.5.2", + "debug": "2.6.1", "del": "2.2.2", "fs-extra-promise": "0.4.1", "keymirror": "0.1.1", "launchd.plist": "0.0.1", "lodash.debounce": "4.0.8", "mousetrap": "1.6.0", - "needle": "1.4.3", + "needle": "1.5.0", "node-uuid": "1.4.7", "promisify-es6": "1.0.2", - "raven": "1.1.1", - "raven-js": "3.9.1", + "raven": "1.1.3", + "raven-js": "3.12.0", "semver": "5.3.0", - "source-map-support": "0.4.8", "spellchecker": "3.3.1", "strip-ansi": "3.0.1", - "winreg": "1.2.2", - "yargs": "6.5.0" + "winreg": "1.2.3", + "yargs": "7.0.1" }, "devDependencies": { - "devtron": "1.4.0" + "devtron": "1.4.0", + "source-map-support": "0.4.11" }, "optionalDependencies": { "nodobjc": "2.1.0" @@ -75,7 +76,7 @@ "sentry": { "dsn": "{{& SENTRY_DSN_PRIVATE }}" }, - "electronVersion": "v1.4.13", + "electronVersion": "v1.4.15", "distrib": "unset", "portable": false, "buildNum": 0, @@ -83,6 +84,7 @@ "themes": { "default": "Default", "dark": "Dark", + "black": "Black", "midnight": "Midnight", "mosaic": "Mosaic" } diff --git a/src/scripts/browser/application.js b/src/scripts/browser/application.js index ddd0d01a..044662c9 100644 --- a/src/scripts/browser/application.js +++ b/src/scripts/browser/application.js @@ -36,6 +36,7 @@ class Application extends EventEmitter { // Others this.notifManager = new NotifManager(); + this.mainWindowManager.setNotifManager(this.notifManager); this.nativeNotifier = new NativeNotifier(this.mainWindowManager); this.autoLauncher = new AutoLauncher(); @@ -45,7 +46,7 @@ class Application extends EventEmitter { // Listeners new AppListenersManager(this.mainWindowManager, this.autoUpdateManager).set(); - new IpcListenersManager(this.notifManager, this.trayManager, this.mainWindowManager).set(); + new IpcListenersManager(this.mainWindowManager).set(); } } diff --git a/src/scripts/browser/main.js b/src/scripts/browser/main.js index bcc0a9a5..8fe92b6d 100755 --- a/src/scripts/browser/main.js +++ b/src/scripts/browser/main.js @@ -111,6 +111,7 @@ if (options.portable) { if (quitIfPrefEnabled()) return; if (printVersionsAndExit()) return; if (enforceSingleInstance()) return; + preReadySetup(); initAndLaunch(); startRepl(); })(); @@ -171,6 +172,10 @@ function startRepl () { } } +function preReadySetup () { + app.disableHardwareAcceleration(); // should be easier on the GPU +} + async function initAndLaunch () { try { await onAppReady(); diff --git a/src/scripts/browser/managers/auto-update-manager.js b/src/scripts/browser/managers/auto-update-manager.js index 009f3c3c..a92c4b8c 100644 --- a/src/scripts/browser/managers/auto-update-manager.js +++ b/src/scripts/browser/managers/auto-update-manager.js @@ -129,7 +129,7 @@ class AutoUpdateManager extends EventEmitter { }, function (response) { if (response === 1) { log('user clicked Download, opening url', downloadUrl); - shell.openExternal(downloadUrl); + shell.openExternal(downloadUrl || global.manifest.homepage); } }); } else if (platform.isWindows && global.options.portable) { @@ -141,7 +141,7 @@ class AutoUpdateManager extends EventEmitter { }, function (response) { if (response === 1) { log('user clicked Download, opening url', downloadUrl); - shell.openExternal(downloadUrl); + shell.openExternal(downloadUrl || global.manifest.homepage); } }); } else { diff --git a/src/scripts/browser/managers/ipc-listeners-manager.js b/src/scripts/browser/managers/ipc-listeners-manager.js index aeb9124f..f06359fa 100644 --- a/src/scripts/browser/managers/ipc-listeners-manager.js +++ b/src/scripts/browser/managers/ipc-listeners-manager.js @@ -1,15 +1,13 @@ -import {app, ipcMain, shell, BrowserWindow, nativeImage} from 'electron'; +import {ipcMain, shell, BrowserWindow} from 'electron'; import EventEmitter from 'events'; -import platform from 'common/utils/platform'; +import urls from 'common/utils/urls'; import prefs from 'browser/utils/prefs'; class IpcListenersManager extends EventEmitter { - constructor (notifManager, trayManager, mainWindowManager) { + constructor (mainWindowManager) { super(); - this.notifManager = notifManager; - this.trayManager = trayManager; this.mainWindowManager = mainWindowManager; } @@ -27,27 +25,14 @@ class IpcListenersManager extends EventEmitter { */ onNotifCount (event, count, badgeDataUrl) { log('on renderer notif-count', count, !!badgeDataUrl || null); - this.notifManager.unreadCount = count; - - // Set icon badge - if (prefs.get('show-notifications-badge')) { - if (platform.isWindows) { - if (count) { - const image = nativeImage.createFromDataURL(badgeDataUrl); - this.mainWindowManager.window.setOverlayIcon(image, count); - } else { - this.mainWindowManager.window.setOverlayIcon(null, ''); - } - } else { - app.setBadgeCount(parseInt(count, 10) || 0); - } + clearTimeout(this._delayedRemoveBadge); + if (count) { + this.mainWindowManager.notifCountChanged(count, badgeDataUrl); + } else { + this._delayedRemoveBadge = setTimeout(() => { + this.mainWindowManager.notifCountChanged(count, badgeDataUrl); + }, 1500); } - - // Update tray - this.trayManager.unreadCountUpdated(count); - - // Update window title - this.mainWindowManager.suffixWindowTitle(count ? ' (' + count + ')' : ''); } /** @@ -61,7 +46,12 @@ class IpcListenersManager extends EventEmitter { * Called when the 'open-url' event is received. */ onOpenUrl (event, url, options) { - if (prefs.get('links-in-browser')) { + url = urls.skipFacebookRedirect(url); + + if (urls.isDownloadUrl(url)) { + log('on renderer open-url, downloading', url); + this.mainWindowManager.window.loadURL(url); + } else if (prefs.get('links-in-browser')) { log('on renderer open-url, externally', url); shell.openExternal(url); } else { diff --git a/src/scripts/browser/managers/main-window-manager.js b/src/scripts/browser/managers/main-window-manager.js index d74d96a2..7c4d758f 100755 --- a/src/scripts/browser/managers/main-window-manager.js +++ b/src/scripts/browser/managers/main-window-manager.js @@ -1,7 +1,8 @@ -import {shell, BrowserWindow, Menu} from 'electron'; +import {app, shell, BrowserWindow, Menu, nativeImage} from 'electron'; import debounce from 'lodash.debounce'; import EventEmitter from 'events'; +import urls from 'common/utils/urls'; import filePaths from 'common/utils/file-paths'; import platform from 'common/utils/platform'; import contextMenu from 'browser/menus/context'; @@ -25,6 +26,10 @@ class MainWindowManager extends EventEmitter { this.menuManager = menuManager; } + setNotifManager (notifManager) { + this.notifManager = notifManager; + } + createWindow () { log('creating main window'); @@ -98,13 +103,18 @@ class MainWindowManager extends EventEmitter { * Called when the 'new-window' event is emitted. */ onNewWindow (event, url) { - // Open urls in an external browser - if (prefs.get('links-in-browser')) { - log('opening url externally', url); + url = urls.skipFacebookRedirect(url); + + if (urls.isDownloadUrl(url)) { + log('on new window, downloading', url); + event.preventDefault(); + this.window.loadURL(url); + } else if (prefs.get('links-in-browser')) { + log('on new window, opening url externally', url); event.preventDefault(); shell.openExternal(url); } else { - log('opening url in-app', url); + log('on new window, opening url in-app', url); } } @@ -237,6 +247,9 @@ class MainWindowManager extends EventEmitter { this.window.setSize(bounds.width, bounds.height, true); this.window.center(); } + + // Remove notifications count + this.notifCountChanged('', null); } /** @@ -294,6 +307,33 @@ class MainWindowManager extends EventEmitter { .replace(new RegExp('\\s+', 'g'), ' '); } + /** + * Update the notifications count everywhere. + */ + notifCountChanged (count, badgeDataUrl) { + this.notifManager.unreadCount = count; + + // Set icon badge + if (prefs.get('show-notifications-badge')) { + if (platform.isWindows) { + if (count) { + const image = nativeImage.createFromDataURL(badgeDataUrl); + this.window.setOverlayIcon(image, count); + } else { + this.window.setOverlayIcon(null, ''); + } + } else { + app.setBadgeCount(parseInt(count, 10) || 0); + } + } + + // Update tray + this.trayManager.unreadCountUpdated(count); + + // Update window title + this.prefixWindowTitle(count ? '(' + count + ') ' : ''); + } + /** * Show and focus or create the main window. */ @@ -306,6 +346,15 @@ class MainWindowManager extends EventEmitter { } } + /** + * Append a prefix to the window title. + */ + prefixWindowTitle (prefix) { + if (this.window) { + this.window.setTitle(prefix + this.initialTitle); + } + } + /** * Append a suffix to the window title. */ diff --git a/src/scripts/browser/managers/notif-manager.js b/src/scripts/browser/managers/notif-manager.js index ca24137e..bf834c8a 100755 --- a/src/scripts/browser/managers/notif-manager.js +++ b/src/scripts/browser/managers/notif-manager.js @@ -4,7 +4,7 @@ class NotifManager extends EventEmitter { constructor () { super(); - this.unreadCount = 0; + this.unreadCount = ''; // number as string; empty string means 0 } } diff --git a/src/scripts/browser/menus/expressions/expr-click.js b/src/scripts/browser/menus/expressions/expr-click.js index 89537460..025714ce 100755 --- a/src/scripts/browser/menus/expressions/expr-click.js +++ b/src/scripts/browser/menus/expressions/expr-click.js @@ -1,8 +1,8 @@ import {app, shell} from 'electron'; import * as piwik from 'browser/services/piwik'; +import * as requestFilter from 'browser/utils/request-filter'; import prefs from 'browser/utils/prefs'; -import requestFilter from 'common/services/request-filter'; /** * Call the handler for the check-for-update event. @@ -115,7 +115,9 @@ export function showWindow () { if (!browserWindow) { browserWindow = global.application.mainWindowManager.window; } - browserWindow.show(); + if (browserWindow) { + browserWindow.show(); + } }; } @@ -189,7 +191,7 @@ export function showInTray (flagExpr) { */ export function showInDock (flagExpr) { return function () { - if (app.dock) { + if (app.dock && app.dock.show && app.dock.hide) { const show = flagExpr.apply(this, arguments); if (show) { app.dock.show(); @@ -211,14 +213,14 @@ export function launchOnStartup (enabledExpr) { .then(() => log('auto launcher enabled')) .catch((err) => { log('could not enable auto-launcher'); - logError(err); + logError(err, true); }); } else { global.application.autoLauncher.disable() .then(() => log('auto launcher disabled')) .catch((err) => { log('could not disable auto-launcher'); - logError(err); + logError(err, true); }); } }; @@ -252,18 +254,12 @@ export function hideTaskbarBadge (flagExpr) { } /** - * Whether the user should appear as online and 'is typing' indicators be sent + * Whether the user should appear as online and 'is typing' indicators be sent. */ export function blockSeenTyping (flagExpr) { return function (menuItem, browserWindow) { - const block = flagExpr.apply(this, arguments); - if (global.ready) { - if (block) { - requestFilter.enable(); - } else { - requestFilter.disable(); - } - } + const shouldBlock = flagExpr.apply(this, arguments); + requestFilter.set(shouldBlock, browserWindow.webContents.session); }; } diff --git a/src/scripts/browser/menus/expressions/expr-value.js b/src/scripts/browser/menus/expressions/expr-value.js index e4fde5a0..905056f9 100755 --- a/src/scripts/browser/menus/expressions/expr-value.js +++ b/src/scripts/browser/menus/expressions/expr-value.js @@ -28,6 +28,15 @@ export function pref (prefName) { }; } +/** + * Negates the given value. + */ +export function not (valueExpr) { + return function () { + return !valueExpr.apply(this, arguments); + }; +} + /** * Sums up two expressions. */ diff --git a/src/scripts/browser/menus/templates/main-app-darwin.js b/src/scripts/browser/menus/templates/main-app-darwin.js index 03c355ee..8dafe5b5 100755 --- a/src/scripts/browser/menus/templates/main-app-darwin.js +++ b/src/scripts/browser/menus/templates/main-app-darwin.js @@ -47,6 +47,16 @@ export default { label: 'Report Stats and Crashes', click: $.setPref('analytics-track', $.key('checked')), parse: $.setLocal('checked', $.pref('analytics-track')) + }, { + type: 'checkbox', + label: 'Switch to Workplace Messenger', + click: $.all( + $.setPref('switch-workplace', $.key('checked')), + $.reloadWindow() + ), + parse: $.all( + $.setLocal('checked', $.pref('switch-workplace')) + ) }, { type: 'separator', allow: !global.options.mas diff --git a/src/scripts/browser/menus/templates/main-help.js b/src/scripts/browser/menus/templates/main-help.js index b33b7597..1b02dc01 100644 --- a/src/scripts/browser/menus/templates/main-help.js +++ b/src/scripts/browser/menus/templates/main-help.js @@ -4,14 +4,10 @@ export default { label: '&Help', role: 'help', submenu: [{ - label: 'Website', - click: $.all( - $.openUrl('http://messengerfordesktop.com/') - ) + label: 'App Website', + click: $.openUrl('https://messengerfordesktop.com/') }, { - label: 'Email', - click: $.all( - $.openUrl('mailto:hello@messengerfordesktop.com'), - ) + label: 'Email Us', + click: $.openUrl('mailto:hello@messengerfordesktop.com') }] }; diff --git a/src/scripts/browser/menus/templates/main-privacy.js b/src/scripts/browser/menus/templates/main-privacy.js index d7a2478d..ac17d0ab 100644 --- a/src/scripts/browser/menus/templates/main-privacy.js +++ b/src/scripts/browser/menus/templates/main-privacy.js @@ -7,8 +7,8 @@ export default { type: 'checkbox', label: 'Block Seen and Typing Indicators', click: $.all( - $.setPref('block-seen-typing', $.key('checked')), - $.blockSeenTyping($.key('checked')) + $.setPref('block-seen-typing', $.key('checked')), + $.blockSeenTyping($.key('checked')) ), parse: $.all( $.setLocal('checked', $.pref('block-seen-typing')) diff --git a/src/scripts/browser/menus/templates/main-view.js b/src/scripts/browser/menus/templates/main-view.js index 2c4abab0..c12d743f 100755 --- a/src/scripts/browser/menus/templates/main-view.js +++ b/src/scripts/browser/menus/templates/main-view.js @@ -90,17 +90,5 @@ export default { // needsWindow: true, // click: $.sendToWebView('switch-conversation', $.val(1000 + index)) // })) - }/*, { - type: 'separator' - }, { - label: 'Send Photo or &Video', - accelerator: 'CmdOrCtrl+O', - needsWindow: true, - click: $.sendToWebView('send-photo-video') - }, { - label: '&Take Photo', - accelerator: 'CmdOrCtrl+P', - needsWindow: true, - click: $.sendToWebView('take-photo') - }*/] + }] }; diff --git a/src/scripts/browser/utils/prefs-defaults.js b/src/scripts/browser/utils/prefs-defaults.js index 8bbd1108..98b0b408 100644 --- a/src/scripts/browser/utils/prefs-defaults.js +++ b/src/scripts/browser/utils/prefs-defaults.js @@ -11,6 +11,7 @@ const defaults = { 'launch-startup-hidden': true, 'launch-quit': false, 'links-in-browser': true, + 'switch-workplace': false, 'block-seen-typing': false, 'close-with-esc': false, 'quit-behaviour-taught': false, diff --git a/src/scripts/browser/utils/prefs.js b/src/scripts/browser/utils/prefs.js index a68955e5..4fc79377 100755 --- a/src/scripts/browser/utils/prefs.js +++ b/src/scripts/browser/utils/prefs.js @@ -17,11 +17,7 @@ function ensureDataLoaded () { data = fs.readJsonSync(prefsPath) || {}; log('prefs data restored'); } catch (err) { - if (err.code === 'ENOENT') { - // ignored - } else { - logError(err); - } + logError(err, true); data = {}; } } @@ -37,7 +33,7 @@ function set (key, value) { fs.outputJson(prefsPath, data, function (err) { if (err) { - logError(err); + logError(err, true); } else { log('saved', key, '=', JSON.stringify(value)); } @@ -56,7 +52,7 @@ function setSync (key, value) { fs.outputJsonSync(prefsPath, data); log('saved', key, '=', JSON.stringify(value)); } catch (err) { - logError(err); + logError(err, true); } } @@ -100,7 +96,7 @@ function unset (key) { fs.outputJson(prefsPath, data, function (err) { if (err) { - logError(err); + logError(err, true); } else { log('unset', key); } @@ -118,7 +114,7 @@ function unsetSync (key) { fs.outputJsonSync(prefsPath, data); log('unset', key); } catch (err) { - logError(err); + logError(err, true); } } @@ -131,7 +127,7 @@ function clear () { fs.outputJson(prefsPath, data, function (err) { if (err) { - logError(err); + logError(err, true); } else { log('all keys cleared'); } diff --git a/src/scripts/browser/utils/request-filter.js b/src/scripts/browser/utils/request-filter.js new file mode 100644 index 00000000..886cba68 --- /dev/null +++ b/src/scripts/browser/utils/request-filter.js @@ -0,0 +1,40 @@ +/** + * URL match patterns to be filteresd. + * @see https://developer.chrome.com/extensions/match_patterns + */ +const URL_PATTERNS = [ + '*://*.facebook.com/*change_read_status*', + '*://*.messenger.com/*change_read_status*', + '*://*.facebook.com/*typ.php*', + '*://*.messenger.com/*typ.php*' +]; + +/** + * Enable request cancelling of urls matched by pattern list. + */ +export function enable (targetSession) { + targetSession.webRequest.onBeforeRequest({urls: URL_PATTERNS}, (details, callback) => { + log('request filter', 'blocked', details.url); + callback({cancel: true}); + }); + log('request filter', 'enabled', URL_PATTERNS.length, 'entries'); +} + +/** + * Disable request cancelling of urls matched by pattern list. + */ +export function disable (targetSession) { + targetSession.webRequest.onBeforeRequest({urls: URL_PATTERNS}, null); + log('request filter', 'disabled'); +} + +/** + * Setter convenience interface. + */ +export function set (shouldEnable, targetSession) { + if (shouldEnable) { + enable(targetSession); + } else { + disable(targetSession); + } +} diff --git a/src/scripts/common/modules/debug.js b/src/scripts/common/modules/debug.js index 8ff754de..2da709bb 100644 --- a/src/scripts/common/modules/debug.js +++ b/src/scripts/common/modules/debug.js @@ -2,11 +2,11 @@ let impl = null; switch (process.type) { case 'browser': - impl = require('debug'); + impl = require('debug/node'); break; case 'renderer': - impl = require('debug'); + impl = require('debug/node'); // Fix for colors and formatting const remoteDebug = require('electron').remote.require('debug'); impl.useColors = function () { @@ -16,9 +16,8 @@ switch (process.type) { } // Force-enable debug -if (global.options.debug && !process.env.DEBUG) { - process.env.DEBUG = global.manifest.name + ':*'; - impl.enable(process.env.DEBUG); +if (global.options.debug) { + impl.enable(process.env.DEBUG || global.manifest.name + ':*'); } export default impl; diff --git a/src/scripts/common/services/request-filter.js b/src/scripts/common/services/request-filter.js deleted file mode 100644 index 44cd4d52..00000000 --- a/src/scripts/common/services/request-filter.js +++ /dev/null @@ -1,58 +0,0 @@ -'use strict'; - -/** - * URL match patterns to be filteresd - * @see https://developer.chrome.com/extensions/match_patterns - * @global - * @constant - */ -const urlPatternList = [ - '*://*.facebook.com/*change_read_status*', - '*://*.messenger.com/*change_read_status*', - '*://*.facebook.com/*typ.php*', - '*://*.messenger.com/*typ.php*' -]; - -/** - * Enable request cancelling of urls matched by pattern list - */ -let enableRequestFilter = () => { - const targetSession = global.application.mainWindowManager.window.webContents.session; - targetSession.webRequest.onBeforeRequest({urls: urlPatternList}, (details, callback) => { - log('request filter', 'blocked', details.url); - callback({cancel: true}); - }); - - log('request filter', 'enabled', urlPatternList.length, 'entries'); -}; - -/** - * Disable request cancelling of urls matched by pattern list - */ -let disableRequestFilter = () => { - const targetSession = global.application.mainWindowManager.window.webContents.session; - targetSession.webRequest.onBeforeRequest({urls: urlPatternList}, null); - - log('request filter', 'disabled'); -}; - -/** - * Setter convenience interface - * @param {Boolean} enable - True/false to enable/disable filtering - */ -let setRequestFilter = (enable) => { - if (enable) { - enableRequestFilter(); - } else { - disableRequestFilter(); - } -}; - -/** - * @exports - */ -export default { - enable: enableRequestFilter, - disable: disableRequestFilter, - set: setRequestFilter -}; diff --git a/src/scripts/common/utils/logger.js b/src/scripts/common/utils/logger.js index 705e7ac0..bb9baab5 100644 --- a/src/scripts/common/utils/logger.js +++ b/src/scripts/common/utils/logger.js @@ -1,10 +1,6 @@ import util from 'util'; import path from 'path'; -import eventCategories from 'common/analytics/categories'; -import eventActions from 'common/analytics/actions'; -import eventNames from 'common/analytics/names'; - function namespaceOfFile (filename) { const app = require('common/electron/app').default; const appPath = path.join(app.getAppPath(), 'scripts') + path.sep; @@ -18,19 +14,10 @@ function namespaceOfFile (filename) { name += ':' + process.type; } - return global.manifest.name + ':' + name; -} + // replace slashes with semicolons + name = name.replace(/\//g, ':'); -function reportToPiwik (namespace, isFatal, err) { - const piwik = require('common/services/piwik').default.getTracker(); - if (piwik) { - piwik.trackEvent( - eventCategories['Logs'], - eventActions['Exception'], - isFatal ? eventNames['Fatal Error'] : eventNames['Error'], - `${namespace}: ${err.name}: ${err.message}` - ); - } + return global.manifest.name + ':' + name; } function reportToSentry (namespace, isFatal, err) { @@ -90,7 +77,6 @@ export function errorLogger (filename, isFatal) { browserLogger.printError(namespace, isFatal, err.stack); if (!skipReporting && !global.options.debug) { - reportToPiwik(namespace, isFatal, err); reportToSentry(namespace, isFatal, err); } }; diff --git a/src/scripts/common/utils/urls.js b/src/scripts/common/utils/urls.js new file mode 100644 index 00000000..ec87e3f4 --- /dev/null +++ b/src/scripts/common/utils/urls.js @@ -0,0 +1,37 @@ +import url from 'url'; + +/** + * Skip opening the link through Facebook. + * It converts [facebook|messenger].com/l.php?u= to . + */ +function skipFacebookRedirect (urlLink) { + const parsed = url.parse(urlLink, true); + log('skip facebook redirect, checking', urlLink); + + if (!parsed || !parsed.hostname || !parsed.pathname) { + return urlLink; + } + + const hostMatches = parsed.hostname.includes('facebook.com') || parsed.hostname.includes('messenger.com'); + const pathMatches = parsed.pathname.includes('/l.php'); + + if (hostMatches && pathMatches && parsed.query.u) { + urlLink = parsed.query.u; + } + + return urlLink; +} + +/** + * Check if the given url is a downloadable file. Currently only detects Facebook CDN urls. + */ +function isDownloadUrl (urlLink) { + const isDlUrl = urlLink.startsWith('https://cdn.fbsbx.com') && urlLink.endsWith('&dl=1'); + log('link is download url', urlLink, isDlUrl); + return isDlUrl; +} + +export default { + skipFacebookRedirect, + isDownloadUrl +}; diff --git a/src/scripts/renderer/init.js b/src/scripts/renderer/init.js index 67796e2b..e5f5ce09 100644 --- a/src/scripts/renderer/init.js +++ b/src/scripts/renderer/init.js @@ -1,7 +1,7 @@ import {remote} from 'electron'; import path from 'path'; -export function inject () { +export function inject (scope) { global.manifest = remote.getGlobal('manifest'); global.options = remote.getGlobal('options'); @@ -13,9 +13,9 @@ export function inject () { // Add loggers to be used in the console const logger = require('common/utils/logger'); - window.log = logger.debugLogger('console:renderer'); - window.logError = logger.errorLogger('console:renderer', false); - window.logFatal = logger.errorLogger('console:renderer', true); + window.log = logger.debugLogger('console:' + scope); + window.logError = logger.errorLogger('console:' + scope, false); + window.logFatal = logger.errorLogger('console:' + scope, true); // Handle errors window.onerror = function (message, source, lineno, colno, error) { diff --git a/src/scripts/renderer/preload/events.js b/src/scripts/renderer/preload/events.js index 6e7f3afa..d5c5e935 100755 --- a/src/scripts/renderer/preload/events.js +++ b/src/scripts/renderer/preload/events.js @@ -8,6 +8,23 @@ ipcRenderer.on('zoom-level', function (event, zoomLevel) { webFrame.setZoomLevel(zoomLevel); }); +// Remove the top banner ad +ipcRenderer.on('remove-top-banner', function (event) { + log('removing top banner ad'); + + // Strip the HTML + const bannerElems = document.getElementsByClassName('_s15'); + for (const bannerElem of bannerElems) { + bannerElem.outerHTML = ''; + } + + // Fix non-automatic resize + if (bannerElems.length) { + webFrame.setZoomLevel(1); + webFrame.setZoomLevel(0); + } +}); + // Set spell checker ipcRenderer.on('spell-checker', function (event, enabled, autoCorrect, langCode) { const chromiumLangCode = langCode.replace('_', '-'); diff --git a/src/scripts/renderer/preload/notification.js b/src/scripts/renderer/preload/notification.js index f02280b5..f51e4ed9 100755 --- a/src/scripts/renderer/preload/notification.js +++ b/src/scripts/renderer/preload/notification.js @@ -11,7 +11,7 @@ window.Notification = (function (Html5Notification) { log('extending HTML5 Notification'); const Notification = function (title, options) { - if (!nativeNotifier.isImplemented || !platform.isDarwin && !platform.isWindows7) { + if (!nativeNotifier.isImplemented || (!platform.isDarwin && !platform.isWindows7)) { log('showing html5 notification', title, options); const notification = new Html5Notification(title, options); diff --git a/src/scripts/renderer/webview/index.js b/src/scripts/renderer/webview/index.js index 16512606..fb423e5f 100755 --- a/src/scripts/renderer/webview/index.js +++ b/src/scripts/renderer/webview/index.js @@ -3,16 +3,19 @@ import path from 'path'; const webView = document.getElementById('wv'); -// Set the user agent and load the app -log('loading', global.manifest.wvUrl); -webView.setAttribute('useragent', navigator.userAgent); -webView.setAttribute('src', global.manifest.wvUrl); - // Fix preload requiring file:// protocol let preloadPath = webView.getAttribute('preload'); preloadPath = 'file://' + path.join(remote.app.getAppPath(), 'html', preloadPath); webView.setAttribute('preload', preloadPath); +// Set the user agent and load the app +const wvSrc = require('common/utils/prefs').default.get('switch-workplace') + ? global.manifest.wvUrlWork + : global.manifest.wvUrl; +log('loading', wvSrc); +webView.setAttribute('useragent', navigator.userAgent); +webView.setAttribute('src', wvSrc); + export default webView; require('renderer/webview/events'); diff --git a/src/scripts/renderer/webview/listeners.js b/src/scripts/renderer/webview/listeners.js index 36d94b82..3d864614 100755 --- a/src/scripts/renderer/webview/listeners.js +++ b/src/scripts/renderer/webview/listeners.js @@ -37,7 +37,7 @@ webView.addEventListener('console-message', function (event) { const msg = event.message.replace(/%c/g, ''); const fwNormal = 'font-weight: normal;'; const fwBold = 'font-weight: bold;'; - console.log('%cWV:%c ' + msg, fwBold, fwNormal); + console.log('WV: ' + msg, fwBold, fwNormal); }); // Listen for title changes to update the badge @@ -57,7 +57,7 @@ webView.addEventListener('page-title-updated', function () { // Handle url clicks webView.addEventListener('new-window', function (event) { - log('sending open-url', event.url); + log('sending open-url', event.frameName, event.url); ipcRenderer.send('open-url', event.url, event.options); }); @@ -114,9 +114,8 @@ webView.addEventListener('dom-ready', function () { // Listen for did-finish-load webView.addEventListener('did-finish-load', function () { // Remove top banner - webView.executeJavaScript("document.getElementsByClassName('_s15')[0].outerHTML = '';"); - webView.setZoomLevel(1); webView.setZoomLevel(0); // Fix non-automatic resize - + webView.send('remove-top-banner'); + // Hide the loading splash screen const loadingSplashDiv = document.querySelector('.loader'); loadingSplashDiv.style.opacity = 0; diff --git a/src/themes/black.css b/src/themes/black.css new file mode 100644 index 00000000..48427d30 --- /dev/null +++ b/src/themes/black.css @@ -0,0 +1,359 @@ +/* @source https://userstyles.org/styles/122582/dark-facebook-messenger-fully-black */ +/* Last update: 2017-02-23 */ + +body, html, #u_0_0, #u_0_0 > div, ._4sp8 { + background-color: #000 !important; + height: 100% !important; + color: #FFF; +} + +._s15 { + height: 0 !important; +} + +/* =========== MID */ +._4sp8, ._4rv3 { + background-color: #000 !important; + color: #FFF !important; +} + +._hw2 ._53ij { + background-color: rgb(39, 39, 39) !important; +} + +._55q { + background-color: #FFF !important; + text-align: center !important; +} + +._55q ._50f7 { + color: #000 !important; +} + +._497p, ._4rv6, ._4ce { + color: #CCC !important; + opacity: 1 !important; +} + +._29_7 ._hh7 { /*incoming message color*/ + background-color: #272727 !important; + color: #E1E1E1 !important; +} + +/*taken from: https://userstyles.org/styles/112397/facebook-messenger-the-dark-side <--- great thanks!*/ +/*sent messages*/ +._o46._nd_ ._hh7 { + background-color: #003265; +} +._o46._nd_ ._hh7:active, ._o46._nd_._-5k ._hh7 { + background-color: #002247; +} + +._hh7._2f5r, ._-5k ._hh7._2f5r { + background-color: #000 !important; +} + +._o46._nd_ ._29_7 ._hh7 a, ._o46._nd_ ._hh7 a { + color: #FFF !important; +} + +._o46._nd_ ._29_7 ._hh7 a:hover, ._o46._nd_ ._hh7 a:hover { + background-color: transparent !important; + text-decoration: none !important; +} + +._o46._nd_ ._29_7 ._hh7 ._2her ._9ah { + background-color: #181d7a !important; +} + +._3i_m ._2her { + color: #181d7a; +} + +div[class^=" language-"] { + color: #000; +} + +/*fix for sticker icon*/ +._4rv6, a._4ce_ { + background-image: url("http://i.imgur.com/EBTGGGi.png") !important; + opacity: 1 !important; +} + +._2t5t { + background-image: url("http://i.imgur.com/6muiRxE.png") !important; +} + +/*============ LOGIN SCREEN */ + +#XMessengerDotComLoginViewPlaceholder ._5hy4, #XMessengerDotComLoginViewPlaceholder ._3403, #XMessengerDotComLoginViewPlaceholder ._5hy9 { + color: #FFF !important; +} + +#XMessengerDotComLoginViewPlaceholder ._4jy0:before { + content: none; +} + +._3v_v > #u_0_0 > ._3v_u { + background-color: #FFF !important; +} + +/*============ LEFT MESSAGE INACTIVE */ +._1ht1 { + background-color: #000 !important; +} + +._1ht6 { + color: #FFF !important; +} + +/* TIMESTAMP */ + +._1ht7 { + color: rgba(255, 255, 255, 0.7) !important; +} + +/* LAST MESSAGE */ +._1htf { + color: rgba(255, 255, 255, 0.5) !important; +} + +/* LEFT MESSAGE UNREAD */ +/*._1ht1[aria-live="polite"] ._4ldz { + animation-name: blink; + animation-duration: 2s; + animation-iteration-count: infinite; +} +@keyframes blink { + 15% {transform: scale(1.05)} + 25% {transform: scale(1)} + 35% {transform: scale(1.1)} + 50% {transform: scale(1)} + +}*/ + +._1ht1[aria-live="polite"] { + background-color: #050505 !important; + animation-name: blink; + animation-duration: 2s; + animation-iteration-count: infinite; +} + +@keyframes blink { + 0% {left: 0px;} + 25% {left:-3px;} + 35% {left: 2px;} + 50% {left:0px;} +} + +#js_6 *{ + color: #FFF !important; +} + +._5l38, ._5t4c, ._11_d ._3xcx, ._11_d ._4g0h { + background-color: #000 !important; + color: #FFF !important; +} + +/* =========== TOP HEAD */ + +._36ic, ._5742, ._4wzs, ._2y8y { + background-color: rgb(39, 39, 39) !important; + border: 0 !important; +} + +._1q5- { + border: 0 !important; +} + +._1q5- ._2y8z, ._1q5- ._58al, ._1n-e, ._2eu- ._3oh- { + color: #FFF !important; +} + +/*._5f0v #js_2d, */._5f0v ._225d, ._2y8_ ._5l38, ._2y8_ ._5l39, ._2y8_ ._225b, ._2y8_ ._4g0h, ._2y8_ ._3xcx, ._2y8_ ._225c, ._2y8_ ._ohe { + background-color: #FFF !important; +} + +._17w2, ._2v6o { + color: #FFF !important; +} + +/*NEW MESSAGE */ + +._2y8y { + background-color: rgb(39, 39, 39) !important; +} + +._3xcx, ._4g0h, ._2y8_ ._364g { + color: #000 !important; +} + +._llj { + margin-top: 35px; +} + +._llj, ._llj ._ohe { + background-color: rgb(39, 39, 39) !important; + border-radius: 10px !important; +} + +._5fx8 { + background-color: #11111B !important; +} + +._58al::-webkit-input-placeholder { + color: #CCC !important; +} + +._58al:-moz-placeholder { /* Firefox 18- */ + color: #CCC !important; +} + +._58al::-moz-placeholder { /* Firefox 19+ */ + color: #CCC !important; +} + +._58al:-ms-input-placeholder { + color: #CCC !important; +} +/* taken from https://css-tricks.com/snippets/css/style-placeholder-text/ */ + +._1qt3 i { + background-color: #FFF !important; + border-radius:25px; +} + +/* ============ RIGHT */ + + + ._4t9y, ._4_j5 { + background-color: #000 !important; + } + + ._3szq { + color: #CCC !important; + padding: 4px 7px 6px !important; + } + +._4rph ._4rpj { + color: #CCC; +} + +._1lj0{ + color: #CCC; +} + +._3eus { + color: rgb(84, 84, 84) !important; +} + +._1jt6 ._2jnq ._2jnt ._3eur ._3oh- { + color: #FFF !important; +} + +/* LABELS */ + +._3tl0 { + color: rgba(255, 255, 255, 0.5) !important; +} + +/* SETTINGS */ +._2c9i .lfloat { + background-color: #FFF !important; +} + +/* BUG REPORT */ +#u_55_5 ._52c9 { + background-color: #FFF !important; +} + +/* MESSAGE ACTIVE */ + +._1ht2 ._1ht6 { + font-weight: bold !important; +} + +._1ht1 img { + opacity: 0.5 !important; +} + +._1ht2 img { + opacity: 1 !important; +} + +._1ht2 { + background-color: #0E0E0E !important; +} + +/* PICTURE/MOVIE LINKS */ +._tih { + border: 1px solid #CCC !important; + border-radius: 5px !important; + background-color: #E7E7E7 !important; +} + +time[class="_3oh-"] { + color: #CCC !important; +} + +/* FORWARD */ +._1e1o { + background-color: #FFF !important; +} + + + +/* GROUP CONVERSATION COLORS */ +._2jnv, ._364g, ._1mf { + color: #FFF !important; +} + +._59s7 ._42ef { + background-color: #FFF !important; +} + +._59s7 ._364g { + color: #000 !important; +} + +/* SETTINGS */ +._59s7 { + color: #000; +} + +._3x6u { + color: #CCC; +} + +/* STICKER STORE */ + +._5ra6, ._59s7 ._5rad, ._59s7 ._5ra5, ._59s7 ._5r5c, ._59s7 ._5ra6 ._ohe { + background-color: rgba(255,255,255,1) !important; +} + +._5ra6 { + padding: 10px !important; + margin: 10px auto 20px auto !important; +} + +/* GAMES */ + +._5f0v, ._5k2t { + color: #000; +} + +._5agj ._4u4_ h3, ._497p._11es h2 { + color: #FFF; +} + +._497p._11es ._4ea2._2kar { + display:none; +} + +._497p._11es ._3quh._30yy._2t_._fy2._2623 { + margin: 5px; + background-color: #002247; + padding:6px; + border-radius: 10px; + color: #FFF; +} diff --git a/src/themes/dark.css b/src/themes/dark.css index c11701e9..9011988d 100644 --- a/src/themes/dark.css +++ b/src/themes/dark.css @@ -1,4 +1,6 @@ -/* @source: https://github.com/auscompgeek/fb-messenger-dark */ +/* @source https://userstyles.org/styles/112397/facebook-messenger-the-dark-side */ +/* Last update: 2017-02-23 */ + /* #141823 is Messenger's normal text colour, white is normal background colour */ /* #1E1E1E and #2D2D30 are Visual Studio, don't ask */ @@ -8,11 +10,11 @@ h2, h3, h4, h5, h6 { ._5743, ._4rph ._4rpj { color: white !important; } -label { +label, ._1wse { color: #aaa; } /* convo search box, to field (new message, add people), other inputs? */ -._2y8y, ._2y8_, ._4jgt, ._58al { +._2y8y, ._2y8_, ._4jgt, input._58al, ._55r1 { background-color: #2d2d30 !important; color: white !important; } @@ -31,10 +33,10 @@ input::-webkit-input-placeholder { } /* main wrapper */ ._4sp8 { - background-color: #1e1e1e; + background-color: #1e1e1e !important; color: #eee; } -/* (not convo list) wrapper */ +/* detail wrapper */ ._1q5- { border-left-color: rgba(255, 255, 255, .1) !important; } @@ -42,6 +44,10 @@ input::-webkit-input-placeholder { ._17w2 { color: white !important; } +/* thread search */ +._33p7 { + background-color: rgba(30, 30, 30, 0.9) !important; +} /* chat area stuff */ /* beginning of convo info */ @@ -49,33 +55,44 @@ input::-webkit-input-placeholder { color: #eee !important; } /* message */ -._hh7 { - background-color: #2d2d30 ; +._29_7 ._hh7, ._29_7._-5k ._hh7 { + background-color: #2d2d30; +} +._29_7 ._hh7 { + color: #ddd; } -._hh7, ._hh7 a { - color: #ddd ; +._hh7 a { + color: inherit !important; } -._hh7:active, ._-5k ._hh7, ._hh7>span>a:hover { - background-color: #333 ; +._29_7 ._hh7:active, ._-5k ._hh7, ._29_7 ._hh7>span>a:hover { + background-color: #333; } /* own message */ -._nd_ ._hh7 { - background-color: #004488 ; +._o46._nd_ ._hh7 { + background-color: #004488; } -._nd_ ._hh7:active, ._nd_._-5k ._hh7, ._nd_ ._hh7>span>a:hover { - background-color: #003377 ; +._o46._nd_ ._hh7:active, ._o46._nd_._-5k ._hh7 { + background-color: #003377; } /* emoji-only messages */ ._hh7._2f5r, ._-5k ._hh7._2f5r { background-color: transparent !important; } -/* link info */ -._5i_d { +/* link info, platform attachment, game leaderboard */ +._5i_d, ._5ssp, ._4ea2 { border-color: rgba(255, 255, 255, .1) !important; } -.__6k, .__6l { +.__6k, .__6l, ._5sr2 { color: #ddd !important; } +._4u4_ > h3, ._4u4- { + color: #eee !important; +} +/* carousel arrow */ +._5x5z, ._5agg, ._5agi { + background-color: #2d2d30 !important; + border-color: #444 !important; +} /* audio message */ ._29_7 ._3czg ._2e-7 ._2e-1, ._29_7 ._3czg ._2e-7 ._2e-2 { background-color: #444 !important; @@ -100,7 +117,7 @@ input::-webkit-input-placeholder { ._hw2 ._53ij { background-color: #040404 !important; } -/* input bar */ +/* composer */ ._4rv3 { background-color: #1e1e1e !important; border-top-color: rgba(255, 255, 255, .1) !important; @@ -121,6 +138,11 @@ input::-webkit-input-placeholder { ._4sp8 .uiBoxYellow { background-color: #662; } +/* code bubbles */ +._wu0 { + background-color: #181818 !important; + border-color: #282828 !important; +} /* convo info, user list */ ._4_j5, ._5l37 { @@ -130,7 +152,7 @@ input::-webkit-input-placeholder { border-left: none !important; } /* convo name, mute label, user in user list, section headings */ -._2jnv, ._3szq, ._364g, ._1lj0 { +._2jnv,._2jnx,._2jnz,._2jnx ._30e7 ._5j5f, ._3szq, ._364g, ._1lj0 { color: #ddd !important; } @@ -156,6 +178,10 @@ input::-webkit-input-placeholder { ._1ht6, ._3q34 { color: #eee !important; } +/* group chat icon dps */ +._57pl, ._57pm { + border-color: transparent !important; +} /* message request from */ ._2kt ._5nxb { color: #ddd !important; @@ -191,16 +217,19 @@ input::-webkit-input-placeholder { background-color: #0066aa !important; } -/* those menus and stickers though */ -._53ij, ._54nf, ._293j, ._55r1 { +/* those menus, stickers, emoji, and games though */ +._53ij, ._54nf, ._293j, ._4lh2 { background-color: #333 !important; } -._5r8a._5r8b { +._5r8a._5r8b, ._1uwz, ._3rh0 { background-color: #222 !important; } -._2i-c ._54nf ._54nh { +._2i-c ._54nf ._54nh, ._4lh2 { color: #ddd !important; } +._4lha ._4lhc, ._4lh7 { + color: #aaa !important; +} ._2i-c ._54ne ._54nh, ._2i-c ._54ne ._54nc, ._2i-c ._54ne { background-color: #0066aa !important; } @@ -215,6 +244,12 @@ input::-webkit-input-placeholder { ._5r8l .uiScrollableArea.contentAfter::after { background-image: linear-gradient(transparent, #333); } +/* sticker and games buttons */ +._4rv6, ._4ce_ { + -webkit-filter: invert(1); + filter: invert(1); + opacity: .6 !important; +} /* menu dropdown triangles */ ._53ik ._53io, ._53il ._53io { -webkit-filter: brightness(20%); @@ -229,22 +264,26 @@ input::-webkit-input-placeholder { -webkit-filter: brightness(80%); filter: brightness(80%); } -._5iwn ._58ak::before, ._23ct, .sp_iPuvEF8GUpL.sx_28245e, -.sp_iHcwOAWgkm0.sx_374c1d, +._5iwm ._58ak::before, ._23ct, ._2xme, :not(._3no3) > ._uwa, ._5jdr ._5jds, -.sp_iHcwOAWgkm0.sx_f0ea69 { +._5nxe .img { -webkit-filter: invert(1); filter: invert(1); } /* messenger dialogs, very important */ -._4-hz, ._4eby, ._4jgp ._4jgu { +._4-hz, ._4eby, ._4jgp ._4jgu, ._12zw { background-color: #222 !important; } ._374c, ._4jgs, ._2c9i ._19jt, ._51l0 .uiInputLabel .__rm + .uiInputLabelLabel, -._5raa, ._5rab { +._5raa, ._5rab, ._4nv_ { color: #ddd !important; } +/* chat emoji picker: selected emoji */ +._-lj ._4rlt { + background-color: #333 !important; + border-color: #666 !important; +} /* report issue dialog, even more so */ /* dialog head */ ._4-i0 { @@ -260,6 +299,13 @@ div._4-i2, div._5a8u, ._4t2a { background-color: #222 !important; color: #eee; } +/* image info */ +._2zn2 { + color: rgba(255, 255, 255, .4) !important; +} +._2zn6 { + color: rgba(255, 255, 255, .6) !important; +} /* what about normal facebook dialogs? */ ._t { background-color: #222 !important; @@ -297,19 +343,19 @@ div._4-i2, div._5a8u, ._4t2a { } /* call page */ -._17cj, ._17cj ._3jne { +._17cj, ._17cj ._3jne, ._38jq { background-color: #1e1e1e !important; } -._17cj ._3jnu, ._17cj ._3jnv { +._17cj ._3jnu, ._17cj ._3jnv, ._fjq { color: rgba(255, 255, 255, .4) !important; } -._17cj ._4j_k { +._17cj ._4j_k, ._fjp { color: #eee !important; } /* stuff that should be grey */ -._ih3, ._3tl0, ._3tl1 ._10w4, ._497p, ._3x6v, ._2v6o, ._3tky, ._5rh4, ._jf4 ._jf3, ._5i_d .__6m, ._2y8z, +._ih3, ._3tl0, ._3tl1 ._10w4, ._497p, ._3x6v, ._2v6o, ._3tky, ._5rh4, ._5qsj, ._jf4 ._jf3, ._5i_d .__6m, ._2y8z, ._4g0h, ._3xcx, ._225b, ._3q35, ._2r2v, ._2n1t, ._1n-e, ._3eus, ._2wy4, ._1u5d ._1u5k, ._3ggt, -._17cj ._2ze8, ._17cj ._cen { +._17cj ._2ze8, ._17cj ._cen, ._5sr7, ._4nw0 { color: rgba(255, 255, 255, .6) !important; } diff --git a/src/themes/midnight.css b/src/themes/midnight.css index 124c5b4c..ffdd13cd 100644 --- a/src/themes/midnight.css +++ b/src/themes/midnight.css @@ -1,30 +1,29 @@ -/** - * @source https://github.com/sindresorhus/caprine/blob/master/dark-mode.css - */ +/* @source https://github.com/sindresorhus/caprine/blob/master/dark-mode.css */ +/* Last update: 2017-02-23 */ body { color: rgba(255, 255, 255, 0.7); background: #192633 !important; } -/* main container? */ +/* Main container? */ ._4sp8 { background: #192633 !important; } -/* main content */ +/* Main content */ ._1q5- { background: #192633 !important; border-left: 1px solid rgba(255, 255, 255, 0.05) !important; } -/* message list: your message bubble */ +/* Message list: your message bubble */ ._o46:not(._nd_) ._hh7 { background: rgba(255, 255, 255, 0.1); color: rgba(255, 255, 255, 0.7); } -/* fix dark mode overriding colors for code snippets */ +/* Fix dark mode overriding colors for code snippets */ ._wu0 { color: black; } @@ -34,22 +33,22 @@ body { color: rgba(255, 255, 255, 0.7); } -/* message list: link in message bubble */ +/* Message list: link in message bubble */ ._hh7 a:hover { background: transparent !important; } -/* message list: link in incoming message bubble */ +/* Message list: link in incoming message bubble */ ._o46._nd_ ._hh7 { color: rgba(255, 255, 255, 0.9); } -/* message list: link preview */ +/* Message list: link preview */ ._5i_d { border: solid 1px rgba(255, 255, 255, 0.05); } -/* message list: link preview text */ +/* Message list: link preview text */ ._5i_d .__6k, ._5i_d .__6l { color: rgba(255, 255, 255, 0.7); @@ -59,36 +58,36 @@ body { color: rgba(255, 255, 255, 0.4); } -/* message list: input bar */ +/* Message list: input bar */ ._4rv3 { background: transparent !important; border-top: solid 1px rgba(255, 255, 255, 0.05); color: rgba(255, 255, 255, 0.7); } -/* message list: timestamp */ +/* Message list: timestamp */ ._497p { color: rgba(255, 255, 255, 0.4); } -/* message list: header above */ +/* Message list: header above */ ._5742 { background: #202C3A !important; border-bottom: none; } -/* message list: header above (invitation) */ +/* Message list: header above (invitation) */ ._2y8z, ._14-7 ._58ah ._58al::-webkit-input-placeholder, ._58-3 { color: rgba(255, 255, 255, 0.4); } -/* message list: header above (invitation) (typed text) */ +/* Message list: header above (invitation) (typed text) */ ._14-7 ._58ah ._58al { color: rgba(255, 255, 255, 0.7); } -/* messages list: user info (is in contacts) */ +/* Messages list: user info (is in contacts) */ ._36zg-e { color: rgba(255, 255, 255, 0.7) !important; } @@ -98,7 +97,7 @@ body { color: rgba(255, 255, 255, 0.4); } -/* messages list: text header above the messages */ +/* Messages list: text header above the messages */ ._17w2, ._ih3 ._3oh-, ._llq ._3oh- { @@ -109,13 +108,13 @@ body { color: rgba(255, 255, 255, 0.4); } -/* contact list: header above */ +/* Contact list: header above */ ._36ic { background: #202C3A !important; border-bottom: none; } -/* contact list: search input */ +/* Contact list: search input */ ._5iwm ._58al { background: rgba(255, 255, 255, 0.1) !important; color: rgba(255, 255, 255, 0.9); @@ -125,22 +124,22 @@ body { color: rgba(255, 255, 255, 0.3); } -/* contact list: background */ +/* Contact list: background */ ._1enh { background: transparent !important; } -/* contact list: person */ +/* Contact list: person */ ._1ht1 { background: transparent !important; } -/* contact list: person (selected) */ +/* Contact list: person (selected) */ ._1ht1._1ht2 { background: rgba(255, 255, 255, 0.03) !important; } -/* contact list: person container */ +/* Contact list: person container */ ._1qt4 { border-top: solid 1px rgba(255, 255, 255, 0.05); } @@ -150,17 +149,17 @@ body { color: rgba(255, 255, 255, 0.7); } -/* contact list: message blurb */ +/* Contact list: message blurb */ ._1htf { color: rgba(255, 255, 255, 0.4); } -/* contact list: timestamp */ +/* Contact list: timestamp */ ._1ht7 { color: rgba(255, 255, 255, 0.2); } -/* contact list: timestamp (unread) */ +/* Contact list: timestamp (unread) */ ._1ht3 ._1ht7 { color: rgba(0, 132, 255, 0.7) } @@ -168,97 +167,97 @@ body { /* contact list: search results */ ._5t4c, ._5t4c ._5l37 { - background: #192633 !important; + color: rgba(255, 255, 255, 0.7) !important; } -/* contact list: search results name */ +/* Contact list: search results name */ ._3q34, ._364g { color: rgba(255, 255, 255, 0.7); } -/* contact list: search results subname */ +/* Contact list: search results subname */ ._3q35 { color: rgba(255, 255, 255, 0.4); } -/* contact list: search result label type */ +/* Contact list: search result label type */ ._3xcx, ._225b { color: rgba(255, 255, 255, 0.4); } -/* contact list: searching text */ +/* Contact list: searching text */ ._4g0h { color: rgba(255, 255, 255, 0.4); } -/* right sidebar */ +/* Right sidebar */ ._4_j5 { background: transparent; border-left: solid 1px rgba(255, 255, 255, 0.05); } -/* right sidebar: headings */ +/* Right sidebar: headings */ ._1lj0 { color: rgba(255, 255, 255, 0.4); } -/* right sidebar: section spacer */ +/* Right sidebar: section spacer */ ._1li- { border-top: solid 1px rgba(255, 255, 255, 0.05); } -/* right sidebar: group chat names */ +/* Right sidebar: group chat names */ ._2jnv { color: rgba(255, 255, 255, 0.7); } -/* right sidebar: messenger type info under name */ +/* Right sidebar: messenger type info under name */ ._3eus { color: rgba(255, 255, 255, 0.4); } -/* right sidebar: mute notification label */ +/* Right sidebar: mute notification label */ ._3szq { color: rgba(255, 255, 255, 0.7); } -/* right sidebar: mute notification time */ +/* Right sidebar: mute notification time */ ._3x6v { color: rgba(255, 255, 255, 0.4); } -/* right sidebar: people list */ +/* Right sidebar: people list */ ._4_j5 ._5l37 { color: rgba(255, 255, 255, 0.4); background: transparent; } -/* right sidebar: people list (add people) */ +/* Right sidebar: people list (add people) */ ._4rph ._4rpj { border-top: solid 1px rgba(255, 255, 255, 0.1); } -/* right sidebar: people list item (name) */ +/* Right sidebar: people list item (name) */ ._364g, ._3x6u, ._4rph ._4rpj { color: rgba(255, 255, 255, 0.7); } -/* new conversation contact list: popup */ +/* New conversation contact list: popup */ ._2y8_ { background: transparent; border: solid 1px rgba(255, 255, 255, 0.05); } -/* new conversation contact list: popup hr */ +/* New conversation contact list: popup hr */ ._5l38 { border-top: 1px solid rgba(255, 255, 255, 0.10); } -/* new conversation contact list: popup hover */ +/* New conversation contact list: popup hover */ ._1k1p ._5l38 { border-top: none; } @@ -267,14 +266,40 @@ body { background-color: rgba(255, 255, 255, 0.05) !important; } -/* dialogs */ +/* Conversation search */ +._33p7 { + background-color: rgb(25, 38, 51); +} +._33p7 ._b-u, +._33p7 ._b-v { + background-color: transparent !important; + background-image: url(/rsrc.php/v3/yb/r/TF9SFeEl2Ka.png) !important; + background-repeat: no-repeat !important; + background-size: auto !important; +} +._33p7 ._b-u { + background-position: 0px -66px !important; +} +._33p7 ._b-v { + background-position: 0 0 !important; +} +._33p7 input { + color: rgba(255, 255, 255, 0.7); + background-color: rgba(255, 255, 255, 0.05); +} +._33p7 ._5iwn ._58ak::before { + -webkit-filter: invert(); + filter: invert(); +} + +/* Dialogs */ ._53ij, ._4eby, ._2c9g { background: #192633 !important; } -/* dialog: title and names */ +/* Dialog: title and names */ ._374c, ._4ebz, ._2c9i ._19jt, @@ -282,29 +307,29 @@ body { color: rgba(255, 255, 255, 0.7) !important; } -/* gif and sticker dialog: hide white triangle */ +/* Gif and sticker dialog: hide white triangle */ ._53io { visibility: hidden; } -/* gif and sticker dialog: style the bottom of the list */ +/* Gif and sticker dialog: style the bottom of the list */ .uiScrollableArea.contentAfter:after { background: linear-gradient(rgba(25, 38, 51, .05), #192633); } -/* sticker dialog: selected header */ +/* Sticker dialog: selected header */ ._5r8a._5r8b, ._eb3:before { background-color: rgba(255, 255, 255, 0.05); } -/* sticker dialog: header borders */ +/* Sticker dialog: header borders */ ._5r8e, ._5r86 { border-color: rgba(255, 255, 255, 0.05); } -/* record dialog: time */ +/* Record dialog: time */ ._3z53 { color: rgba(255, 255, 255, 0.7); } diff --git a/src/themes/mosaic.css b/src/themes/mosaic.css index b2d024e2..6981d064 100644 --- a/src/themes/mosaic.css +++ b/src/themes/mosaic.css @@ -1,4 +1,5 @@ -/* @source: https://userstyles.org/styles/112722/messenger-com-dark */ +/* @source https://userstyles.org/styles/112722/messenger-com-dark */ +/* Last update: 2017-02-23 */ body { color: #DCDCCC; diff --git a/tasks/compile.coffee b/tasks/compile.coffee index 26252d7f..ca7cf299 100644 --- a/tasks/compile.coffee +++ b/tasks/compile.coffee @@ -42,7 +42,8 @@ args = require './args' loggerIgnore = fs.readFileSync('./src/.loggerignore', 'utf8') .split('\n').filter((rule) -> !!rule).map((rule) -> '!' + rule.trim()) excludeHeaderFilter = filter ['**/*'].concat(loggerIgnore), {restore: true} - sourceMapHeader = "if (process.type === 'browser') { require('source-map-support').install(); }" + sourceMapHeader = "if (process.type === 'browser') { " + + "try { require('source-map-support').install(); } catch(ignored) {} }" loggerHeader = [ "var log = require('common/utils/logger').debugLogger(__filename);" "var logError = require('common/utils/logger').errorLogger(__filename, false);"