From 760ab16de4c0560b6da86a1b339613b1e12a220a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Du=C5=A1an=20Simi=C4=87?= Date: Wed, 26 Jul 2023 21:11:15 +0200 Subject: [PATCH] Workaround for electron-store in renderer (#2037) --- source/autoplay.ts | 7 ++--- source/browser.ts | 66 +++++++++++++++++++++++++++------------------- source/config.ts | 5 ++-- source/emoji.ts | 4 +-- source/index.ts | 55 +++++++++++++++++++++++++++----------- 5 files changed, 87 insertions(+), 50 deletions(-) diff --git a/source/autoplay.ts b/source/autoplay.ts index b9378b881..8a9ed5bd6 100644 --- a/source/autoplay.ts +++ b/source/autoplay.ts @@ -1,11 +1,12 @@ -import config from './config'; +import {ipcRenderer as ipc} from 'electron-better-ipc'; import selectors from './browser/selectors'; const conversationId = 'conversationWindow'; const disabledVideoId = 'disabled_autoplay'; -export function toggleVideoAutoplay(): void { - if (config.get('autoplayVideos')) { +export async function toggleVideoAutoplay(): Promise { + const autoplayVideos = await ipc.callMain('get-config-autoplayVideos'); + if (autoplayVideos) { // Stop the observers conversationDivObserver.disconnect(); videoObserver.disconnect(); diff --git a/source/browser.ts b/source/browser.ts index d964757ba..d8cf68317 100644 --- a/source/browser.ts +++ b/source/browser.ts @@ -4,7 +4,6 @@ import {is} from 'electron-util'; import elementReady = require('element-ready'); import {nativeTheme} from '@electron/remote'; import selectors from './browser/selectors'; -import config from './config'; import {toggleVideoAutoplay} from './autoplay'; import {sendConversationList} from './browser/conversation-list'; import {IToggleSounds} from './types'; @@ -118,7 +117,8 @@ ipc.answerMain('new-room', async () => { }); ipc.answerMain('log-out', async () => { - if (config.get('useWorkChat')) { + const useWorkChat = await ipc.callMain('get-config-useWorkChat'); + if (useWorkChat) { document.querySelector('._5lxs._3qct._p')!.click(); // Menu creation is slow @@ -275,8 +275,9 @@ ipc.answerMain('toggle-mute-notifications', async () => { return !notificationCheckbox.checked; }); -ipc.answerMain('toggle-message-buttons', () => { - document.body.classList.toggle('show-message-buttons', !config.get('showMessageButtons')); +ipc.answerMain('toggle-message-buttons', async () => { + const showMessageButtons = await ipc.callMain('get-config-showMessageButtons'); + document.body.classList.toggle('show-message-buttons', !showMessageButtons); }); ipc.answerMain('show-active-contacts-view', async () => { @@ -303,8 +304,10 @@ ipc.answerMain('reload', () => { location.reload(); }); -function setTheme(): void { - nativeTheme.themeSource = config.get('theme'); +async function setTheme(): Promise { + type ThemeSource = typeof nativeTheme.themeSource; + const theme = await ipc.callMain('get-config-theme'); + nativeTheme.themeSource = theme; setThemeElement(document.documentElement); updateVibrancy(); } @@ -373,20 +376,23 @@ async function observeTheme(): Promise { } } -function setPrivateMode(): void { - document.documentElement.classList.toggle('private-mode', config.get('privateMode')); +async function setPrivateMode(): Promise { + const privateMode = await ipc.callMain('get-config-privateMode'); + document.documentElement.classList.toggle('private-mode', privateMode); if (is.macos) { sendConversationList(); } } -function updateVibrancy(): void { +async function updateVibrancy(): Promise { const {classList} = document.documentElement; classList.remove('sidebar-vibrancy', 'full-vibrancy'); - switch (config.get('vibrancy')) { + const vibrancy = await ipc.callMain('get-config-vibrancy'); + + switch (vibrancy) { case 'sidebar': classList.add('sidebar-vibrancy'); break; @@ -399,12 +405,14 @@ function updateVibrancy(): void { ipc.callMain('set-vibrancy'); } -function updateSidebar(): void { +async function updateSidebar(): Promise { const {classList} = document.documentElement; classList.remove('sidebar-hidden', 'sidebar-force-narrow', 'sidebar-force-wide'); - switch (config.get('sidebar')) { + const sidebar = await ipc.callMain('get-config-sidebar'); + + switch (sidebar) { case 'hidden': classList.add('sidebar-hidden'); break; @@ -484,23 +492,25 @@ ipc.answerMain('render-native-emoji', (emoji: string): string => { return dataUrl; }); -ipc.answerMain('zoom-reset', () => { - setZoom(1); +ipc.answerMain('zoom-reset', async () => { + await setZoom(1); }); -ipc.answerMain('zoom-in', () => { - const zoomFactor = config.get('zoomFactor') + 0.1; +ipc.answerMain('zoom-in', async () => { + let zoomFactor = await ipc.callMain('get-config-zoomFactor'); + zoomFactor += 0.1; if (zoomFactor < 1.6) { - setZoom(zoomFactor); + await setZoom(zoomFactor); } }); -ipc.answerMain('zoom-out', () => { - const zoomFactor = config.get('zoomFactor') - 0.1; +ipc.answerMain('zoom-out', async () => { + let zoomFactor = await ipc.callMain('get-config-zoomFactor'); + zoomFactor -= 0.1; if (zoomFactor >= 0.8) { - setZoom(zoomFactor); + await setZoom(zoomFactor); } }); @@ -563,10 +573,10 @@ function selectedConversationIndex(offset = 0): number { return ((index % list.length) + list.length) % list.length; } -function setZoom(zoomFactor: number): void { +async function setZoom(zoomFactor: number): Promise { const node = document.querySelector('#zoomFactor')!; node.textContent = `${selectors.conversationSelector} {zoom: ${zoomFactor} !important}`; - config.set('zoomFactor', zoomFactor); + await ipc.callMain('set-config-zoomFactor', zoomFactor); } async function withConversationMenu(callback: () => void): Promise { @@ -726,7 +736,7 @@ document.addEventListener('DOMContentLoaded', async () => { document.body.append(style); // Set the zoom factor if it was set before quitting - const zoomFactor = config.get('zoomFactor'); + const zoomFactor = await ipc.callMain('get-config-zoomFactor'); setZoom(zoomFactor); // Enable OS specific styles @@ -778,12 +788,14 @@ window.addEventListener('dblclick', (event: Event) => { passive: true, }); -window.addEventListener('load', () => { +window.addEventListener('load', async () => { if (location.pathname.startsWith('/login')) { const keepMeSignedInCheckbox = document.querySelector('#u_0_0')!; - keepMeSignedInCheckbox.checked = config.get('keepMeSignedIn'); - keepMeSignedInCheckbox.addEventListener('change', () => { - config.set('keepMeSignedIn', !config.get('keepMeSignedIn')); + const keepMeSignedInConfig = await ipc.callMain('get-config-keepMeSignedIn'); + keepMeSignedInCheckbox.checked = keepMeSignedInConfig; + keepMeSignedInCheckbox.addEventListener('change', async () => { + const keepMeSignedIn = await ipc.callMain('get-config-keepMeSignedIn'); + await ipc.callMain('set-config-keepMeSignedIn', keepMeSignedIn); }); } }); diff --git a/source/config.ts b/source/config.ts index d54494984..d900f07de 100644 --- a/source/config.ts +++ b/source/config.ts @@ -1,7 +1,8 @@ import Store from 'electron-store'; import {is} from 'electron-util'; +import {EmojiStyle} from './emoji'; -type StoreType = { +export type StoreType = { theme: 'system' | 'light' | 'dark'; privateMode: boolean; showPrivateModePrompt: boolean; @@ -30,7 +31,7 @@ type StoreType = { typingIndicator: boolean; deliveryReceipt: boolean; }; - emojiStyle: 'native' | 'facebook-3-0' | 'messenger-1-0' | 'facebook-2-2'; + emojiStyle: EmojiStyle; useWorkChat: boolean; sidebar: 'default' | 'hidden' | 'narrow' | 'wide'; autoHideMenuBar: boolean; diff --git a/source/emoji.ts b/source/emoji.ts index d818b7704..032a9575b 100644 --- a/source/emoji.ts +++ b/source/emoji.ts @@ -8,8 +8,8 @@ import { } from 'electron'; import {is} from 'electron-util'; import {memoize} from 'lodash'; -import config from './config'; import {showRestartDialog, getWindow, sendBackgroundAction} from './util'; +import config from './config'; // The list of emojis that aren't supported by older emoji (facebook-2-2, messenger-1-0) // Based on https://emojipedia.org/facebook/3.0/new/ @@ -298,7 +298,7 @@ with this: https://static.xx.fbcdn.net/images/emoji.php/v9/z27/2/32/1f600.png (see here) ^ */ export async function process(url: string): Promise { - const emojiStyle = config.get('emojiStyle') as EmojiStyle; + const emojiStyle = config.get('emojiStyle'); const emojiSetCode = codeForEmojiStyle(emojiStyle); // The character code is the filename without the extension. diff --git a/source/index.ts b/source/index.ts index 13e595f02..a4d5ee9a9 100644 --- a/source/index.ts +++ b/source/index.ts @@ -11,8 +11,9 @@ import { Notification, MenuItemConstructorOptions, systemPreferences, + nativeTheme, } from 'electron'; -import {ipcMain} from 'electron-better-ipc'; +import {ipcMain as ipc} from 'electron-better-ipc'; import {autoUpdater} from 'electron-updater'; import electronDl from 'electron-dl'; import electronContextMenu from 'electron-context-menu'; @@ -22,7 +23,7 @@ import {is, darkMode} from 'electron-util'; import {bestFacebookLocaleFor} from 'facebook-locales'; import doNotDisturb from '@sindresorhus/do-not-disturb'; import updateAppMenu from './menu'; -import config from './config'; +import config, {StoreType} from './config'; import tray from './tray'; import {sendAction, sendBackgroundAction, messengerDomain, stripTrackingFromUrl} from './util'; import {process as processEmojiUrl} from './emoji'; @@ -30,7 +31,7 @@ import ensureOnline from './ensure-online'; import {setUpMenuBarMode} from './menu-bar-mode'; import {caprineIconPath} from './constants'; -ipcMain.setMaxListeners(100); +ipc.setMaxListeners(100); electronDebug({ isEnabled: true, // TODO: This is only enabled to allow `Command+R` because messenger.com sometimes gets stuck after computer waking up @@ -143,7 +144,7 @@ async function updateBadge(conversations: Conversation[]): Promise { mainWindow.setOverlayIcon(null, ''); } else { // Delegate drawing of overlay icon to renderer process - updateOverlayIcon(await ipcMain.callRenderer(mainWindow, 'render-overlay-icon', messageCount)); + updateOverlayIcon(await ipc.callRenderer(mainWindow, 'render-overlay-icon', messageCount)); } } } @@ -161,7 +162,7 @@ function updateTrayIcon(): void { } } -ipcMain.answerRenderer('update-tray-icon', updateTrayIcon); +ipc.answerRenderer('update-tray-icon', updateTrayIcon); interface BeforeSendHeadersResponse { cancel?: boolean; @@ -399,7 +400,7 @@ function createMainWindow(): BrowserWindow { type: 'checkbox', checked: config.get('notificationsMuted'), async click() { - setNotificationsMute(await ipcMain.callRenderer(mainWindow, 'toggle-mute-notifications')); + setNotificationsMute(await ipc.callRenderer(mainWindow, 'toggle-mute-notifications')); }, }; @@ -411,13 +412,13 @@ function createMainWindow(): BrowserWindow { app.dock.show(); } - ipcMain.once('conversations', () => { + ipc.once('conversations', () => { // Messenger sorts the conversations by unread state. // We select the first conversation from the list. sendAction('jump-to-conversation', 1); }); - ipcMain.answerRenderer('conversations', (conversations: Conversation[]) => { + ipc.answerRenderer('conversations', (conversations: Conversation[]) => { if (conversations.length === 0) { return; } @@ -436,7 +437,7 @@ function createMainWindow(): BrowserWindow { } // Update badge on conversations change - ipcMain.answerRenderer('conversations', async (conversations: Conversation[]) => { + ipc.answerRenderer('conversations', async (conversations: Conversation[]) => { updateBadge(conversations); }); @@ -482,10 +483,10 @@ function createMainWindow(): BrowserWindow { } if (is.macos) { - ipcMain.answerRenderer('update-dnd-mode', async (initialSoundsValue: boolean) => { + ipc.answerRenderer('update-dnd-mode', async (initialSoundsValue: boolean) => { doNotDisturb.on('change', (doNotDisturb: boolean) => { isDNDEnabled = doNotDisturb; - ipcMain.callRenderer(mainWindow, 'toggle-sounds', {checked: isDNDEnabled ? false : initialSoundsValue}); + ipc.callRenderer(mainWindow, 'toggle-sounds', {checked: isDNDEnabled ? false : initialSoundsValue}); }); isDNDEnabled = await doNotDisturb.isEnabled(); @@ -494,11 +495,11 @@ function createMainWindow(): BrowserWindow { }); } - setNotificationsMute(await ipcMain.callRenderer(mainWindow, 'toggle-mute-notifications', { + setNotificationsMute(await ipc.callRenderer(mainWindow, 'toggle-mute-notifications', { defaultStatus: config.get('notificationsMuted'), })); - ipcMain.callRenderer(mainWindow, 'toggle-message-buttons', config.get('showMessageButtons')); + ipc.callRenderer(mainWindow, 'toggle-message-buttons', config.get('showMessageButtons')); await webContents.executeJavaScript( readFileSync(path.join(__dirname, 'notifications-isolated.js'), 'utf8'), @@ -584,7 +585,7 @@ function createMainWindow(): BrowserWindow { })(); if (is.macos) { - ipcMain.answerRenderer('set-vibrancy', () => { + ipc.answerRenderer('set-vibrancy', () => { mainWindow.setBackgroundColor('#80FFFFFF'); // Transparent, workaround for vibrancy issue. mainWindow.setVibrancy('sidebar'); }); @@ -598,7 +599,7 @@ function toggleMaximized(): void { } } -ipcMain.answerRenderer('titlebar-doubleclick', () => { +ipc.answerRenderer('titlebar-doubleclick', () => { if (is.macos) { const doubleClickAction = systemPreferences.getUserDefault('AppleActionOnDoubleClick', 'string'); @@ -631,7 +632,7 @@ app.on('before-quit', () => { const notifications = new Map(); -ipcMain.answerRenderer( +ipc.answerRenderer( 'notification', ({id, title, body, icon, silent}: {id: number; title: string; body: string; icon: string; silent: boolean}) => { const notification = new Notification({ @@ -665,3 +666,25 @@ ipcMain.answerRenderer( notification.show(); }, ); + +type ThemeSource = typeof nativeTheme.themeSource; + +ipc.answerRenderer('get-config-useWorkChat', async () => config.get('useWorkChat')); +ipc.answerRenderer('get-config-showMessageButtons', async () => config.get('showMessageButtons')); +ipc.answerRenderer('get-config-theme', async () => config.get('theme')); +ipc.answerRenderer('get-config-privateMode', async () => config.get('privateMode')); +ipc.answerRenderer('get-config-vibrancy', async () => config.get('vibrancy')); +ipc.answerRenderer('get-config-sidebar', async () => config.get('sidebar')); +ipc.answerRenderer('get-config-zoomFactor', async () => config.get('zoomFactor')); +ipc.answerRenderer('set-config-zoomFactor', async zoomFactor => { + config.set('zoomFactor', zoomFactor); +}); +ipc.answerRenderer('get-config-keepMeSignedIn', async () => config.get('keepMeSignedIn')); +ipc.answerRenderer('set-config-keepMeSignedIn', async keepMeSignedIn => { + config.set('keepMeSignedIn', keepMeSignedIn); +}); +ipc.answerRenderer('get-config-autoplayVideos', async () => config.get('autoplayVideos')); +ipc.answerRenderer('get-config-emojiStyle', async () => config.get('emojiStyle')); +ipc.answerRenderer('set-config-emojiStyle', async emojiStyle => { + config.set('emojiStyle', emojiStyle); +});