aboutsummaryrefslogtreecommitdiffstats
path: root/packages/renderer/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/renderer/src')
-rw-r--r--packages/renderer/src/components/App.tsx6
-rw-r--r--packages/renderer/src/components/BrowserViewPlaceholder.tsx14
-rw-r--r--packages/renderer/src/components/Sidebar.tsx4
-rw-r--r--packages/renderer/src/components/StoreProvider.tsx2
-rw-r--r--packages/renderer/src/components/ThemeProvider.tsx8
-rw-r--r--packages/renderer/src/components/ToggleDarkModeButton.tsx9
-rw-r--r--packages/renderer/src/devTools.ts21
-rw-r--r--packages/renderer/src/index.tsx13
-rw-r--r--packages/renderer/src/stores/RendererEnv.ts4
-rw-r--r--packages/renderer/src/stores/RendererStore.ts21
-rw-r--r--packages/renderer/src/utils/log.ts50
11 files changed, 102 insertions, 50 deletions
diff --git a/packages/renderer/src/components/App.tsx b/packages/renderer/src/components/App.tsx
index 8bd3dd8..1174bbb 100644
--- a/packages/renderer/src/components/App.tsx
+++ b/packages/renderer/src/components/App.tsx
@@ -21,10 +21,10 @@
21import Box from '@mui/material/Box'; 21import Box from '@mui/material/Box';
22import React from 'react'; 22import React from 'react';
23 23
24import { BrowserViewPlaceholder } from './BrowserViewPlaceholder'; 24import BrowserViewPlaceholder from './BrowserViewPlaceholder';
25import { Sidebar } from './Sidebar'; 25import Sidebar from './Sidebar';
26 26
27export function App(): JSX.Element { 27export default function App(): JSX.Element {
28 return ( 28 return (
29 <Box 29 <Box
30 sx={{ 30 sx={{
diff --git a/packages/renderer/src/components/BrowserViewPlaceholder.tsx b/packages/renderer/src/components/BrowserViewPlaceholder.tsx
index 6aa6b7b..c671983 100644
--- a/packages/renderer/src/components/BrowserViewPlaceholder.tsx
+++ b/packages/renderer/src/components/BrowserViewPlaceholder.tsx
@@ -18,17 +18,15 @@
18 * SPDX-License-Identifier: AGPL-3.0-only 18 * SPDX-License-Identifier: AGPL-3.0-only
19 */ 19 */
20 20
21import { throttle } from 'lodash';
22import { observer } from 'mobx-react-lite';
23import Box from '@mui/material/Box'; 21import Box from '@mui/material/Box';
22import throttle from 'lodash-es/throttle';
23import { observer } from 'mobx-react-lite';
24import React, { useCallback, useRef } from 'react'; 24import React, { useCallback, useRef } from 'react';
25 25
26import { useStore } from './StoreProvider'; 26import { useStore } from './StoreProvider';
27 27
28export const BrowserViewPlaceholder = observer(function BrowserViewPlaceholder() { 28export default observer(() => {
29 const { 29 const store = useStore();
30 setBrowserViewBounds,
31 } = useStore();
32 30
33 const onResize = useCallback(throttle(([entry]: ResizeObserverEntry[]) => { 31 const onResize = useCallback(throttle(([entry]: ResizeObserverEntry[]) => {
34 if (entry) { 32 if (entry) {
@@ -38,14 +36,14 @@ export const BrowserViewPlaceholder = observer(function BrowserViewPlaceholder()
38 width, 36 width,
39 height, 37 height,
40 } = entry.target.getBoundingClientRect(); 38 } = entry.target.getBoundingClientRect();
41 setBrowserViewBounds({ 39 store.setBrowserViewBounds({
42 x, 40 x,
43 y, 41 y,
44 width, 42 width,
45 height, 43 height,
46 }); 44 });
47 } 45 }
48 }, 100), [setBrowserViewBounds]); 46 }, 100), [store]);
49 47
50 const resizeObserverRef = useRef<ResizeObserver | null>(null); 48 const resizeObserverRef = useRef<ResizeObserver | null>(null);
51 49
diff --git a/packages/renderer/src/components/Sidebar.tsx b/packages/renderer/src/components/Sidebar.tsx
index 6c79932..44a47b0 100644
--- a/packages/renderer/src/components/Sidebar.tsx
+++ b/packages/renderer/src/components/Sidebar.tsx
@@ -21,9 +21,9 @@
21import Box from '@mui/material/Box'; 21import Box from '@mui/material/Box';
22import React from 'react'; 22import React from 'react';
23 23
24import { ToggleDarkModeButton } from './ToggleDarkModeButton'; 24import ToggleDarkModeButton from './ToggleDarkModeButton';
25 25
26export function Sidebar(): JSX.Element { 26export default function Sidebar(): JSX.Element {
27 return ( 27 return (
28 <Box 28 <Box
29 sx={(theme) => ({ 29 sx={(theme) => ({
diff --git a/packages/renderer/src/components/StoreProvider.tsx b/packages/renderer/src/components/StoreProvider.tsx
index da1e699..cde6a31 100644
--- a/packages/renderer/src/components/StoreProvider.tsx
+++ b/packages/renderer/src/components/StoreProvider.tsx
@@ -32,7 +32,7 @@ export function useStore(): RendererStore {
32 return store; 32 return store;
33} 33}
34 34
35export function StoreProvider({ children, store }: { 35export default function StoreProvider({ children, store }: {
36 children: JSX.Element | JSX.Element[], 36 children: JSX.Element | JSX.Element[],
37 store: RendererStore, 37 store: RendererStore,
38}): JSX.Element { 38}): JSX.Element {
diff --git a/packages/renderer/src/components/ThemeProvider.tsx b/packages/renderer/src/components/ThemeProvider.tsx
index 9215f5c..eacaa52 100644
--- a/packages/renderer/src/components/ThemeProvider.tsx
+++ b/packages/renderer/src/components/ThemeProvider.tsx
@@ -18,18 +18,18 @@
18 * SPDX-License-Identifier: AGPL-3.0-only 18 * SPDX-License-Identifier: AGPL-3.0-only
19 */ 19 */
20 20
21import { observer } from 'mobx-react-lite';
22import { 21import {
23 unstable_createMuiStrictModeTheme as createTheme, 22 unstable_createMuiStrictModeTheme as createTheme,
24 ThemeProvider as MuiThemeProvider, 23 ThemeProvider as MuiThemeProvider,
25} from '@mui/material/styles'; 24} from '@mui/material/styles';
25import { observer } from 'mobx-react-lite';
26import React from 'react'; 26import React from 'react';
27 27
28import { useStore } from './StoreProvider'; 28import { useStore } from './StoreProvider';
29 29
30export const ThemeProvider = observer(function ThemeProvider({ children }: { 30export default observer(({ children }: {
31 children: JSX.Element | JSX.Element[], 31 children: JSX.Element | JSX.Element[];
32}) { 32}) => {
33 const { shared: { shouldUseDarkColors } } = useStore(); 33 const { shared: { shouldUseDarkColors } } = useStore();
34 34
35 const theme = createTheme({ 35 const theme = createTheme({
diff --git a/packages/renderer/src/components/ToggleDarkModeButton.tsx b/packages/renderer/src/components/ToggleDarkModeButton.tsx
index 1b6757e..c8ffdf0 100644
--- a/packages/renderer/src/components/ToggleDarkModeButton.tsx
+++ b/packages/renderer/src/components/ToggleDarkModeButton.tsx
@@ -18,21 +18,22 @@
18 * SPDX-License-Identifier: AGPL-3.0-only 18 * SPDX-License-Identifier: AGPL-3.0-only
19 */ 19 */
20 20
21import { observer } from 'mobx-react-lite';
22import DarkModeIcon from '@mui/icons-material/DarkMode'; 21import DarkModeIcon from '@mui/icons-material/DarkMode';
23import LightModeIcon from '@mui/icons-material/LightMode'; 22import LightModeIcon from '@mui/icons-material/LightMode';
24import IconButton from '@mui/material/IconButton'; 23import IconButton from '@mui/material/IconButton';
24import { observer } from 'mobx-react-lite';
25import React from 'react'; 25import React from 'react';
26 26
27import { useStore } from './StoreProvider'; 27import { useStore } from './StoreProvider';
28 28
29export const ToggleDarkModeButton = observer(function ToggleDarkModeButton() { 29export default observer(() => {
30 const { shared: { shouldUseDarkColors }, toggleDarkMode } = useStore(); 30 const store = useStore();
31 const { shared: { shouldUseDarkColors } } = store;
31 32
32 return ( 33 return (
33 <IconButton 34 <IconButton
34 aria-label="Toggle dark mode" 35 aria-label="Toggle dark mode"
35 onClick={() => toggleDarkMode()} 36 onClick={() => store.toggleDarkMode()}
36 > 37 >
37 {shouldUseDarkColors ? <LightModeIcon /> : <DarkModeIcon />} 38 {shouldUseDarkColors ? <LightModeIcon /> : <DarkModeIcon />}
38 </IconButton> 39 </IconButton>
diff --git a/packages/renderer/src/devTools.ts b/packages/renderer/src/devTools.ts
index 3ec66aa..3d3ba99 100644
--- a/packages/renderer/src/devTools.ts
+++ b/packages/renderer/src/devTools.ts
@@ -32,31 +32,24 @@ import type { IAnyStateTreeNode } from 'mobx-state-tree';
32 * However, we don't bundle `remotedev` in production, so the call would fail anyways. 32 * However, we don't bundle `remotedev` in production, so the call would fail anyways.
33 * 33 *
34 * @param model The store to connect to the redux devtools. 34 * @param model The store to connect to the redux devtools.
35 * @return A promise that resolves when the store was exposed to the devtools.
35 * @see https://github.com/SocketCluster/socketcluster-client/issues/118#issuecomment-469064682 36 * @see https://github.com/SocketCluster/socketcluster-client/issues/118#issuecomment-469064682
36 */ 37 */
37async function exposeToReduxDevtoolsAsync(model: IAnyStateTreeNode): Promise<void> { 38export async function exposeToReduxDevtools(model: IAnyStateTreeNode): Promise<void> {
38 (window as { global?: unknown }).global = window; 39 (window as { global?: unknown }).global = window;
39 40
41 // Hack to load dev dependencies on demand.
40 const [remotedev, { connectReduxDevtools }] = await Promise.all([ 42 const [remotedev, { connectReduxDevtools }] = await Promise.all([
41 // @ts-ignore 43 // @ts-expect-error `remotedev` has no typings.
42 import('remotedev'), 44 // eslint-disable-next-line import/no-extraneous-dependencies
45 import('remotedev') as unknown,
46 // eslint-disable-next-line import/no-extraneous-dependencies
43 import('mst-middlewares'), 47 import('mst-middlewares'),
44 ]); 48 ]);
45 connectReduxDevtools(remotedev, model); 49 connectReduxDevtools(remotedev, model);
46} 50}
47 51
48/** 52/**
49 * Connects the `model` to the redux devtools extension.
50 *
51 * @param model The store to connect to the redux devtools.
52 */
53export function exposeToReduxDevtools(model: IAnyStateTreeNode): void {
54 exposeToReduxDevtoolsAsync(model).catch((err) => {
55 console.error('Could not connect to Redux devtools', err);
56 });
57}
58
59/**
60 * Sends a message to the main process to reload all services when 53 * Sends a message to the main process to reload all services when
61 * `build/watch.js` sends a reload event on bundle write. 54 * `build/watch.js` sends a reload event on bundle write.
62 */ 55 */
diff --git a/packages/renderer/src/index.tsx b/packages/renderer/src/index.tsx
index 1626bef..d900e50 100644
--- a/packages/renderer/src/index.tsx
+++ b/packages/renderer/src/index.tsx
@@ -26,14 +26,17 @@ import CssBaseline from '@mui/material/CssBaseline';
26import React from 'react'; 26import React from 'react';
27import { render } from 'react-dom'; 27import { render } from 'react-dom';
28 28
29import { App } from './components/App'; 29import App from './components/App';
30import { StoreProvider } from './components/StoreProvider'; 30import StoreProvider from './components/StoreProvider';
31import { ThemeProvider } from './components/ThemeProvider'; 31import ThemeProvider from './components/ThemeProvider';
32import { exposeToReduxDevtools, hotReloadServices } from './devTools'; 32import { exposeToReduxDevtools, hotReloadServices } from './devTools';
33import { createAndConnectRendererStore } from './stores/RendererStore'; 33import { createAndConnectRendererStore } from './stores/RendererStore';
34import { getLogger } from './utils/log';
34 35
35const isDevelopment = import.meta.env.MODE === 'development'; 36const isDevelopment = import.meta.env.MODE === 'development';
36 37
38const log = getLogger('index');
39
37if (isDevelopment) { 40if (isDevelopment) {
38 hotReloadServices(); 41 hotReloadServices();
39 document.title = `[dev] ${document.title}`; 42 document.title = `[dev] ${document.title}`;
@@ -42,7 +45,9 @@ if (isDevelopment) {
42const store = createAndConnectRendererStore(window.sophieRenderer); 45const store = createAndConnectRendererStore(window.sophieRenderer);
43 46
44if (isDevelopment) { 47if (isDevelopment) {
45 exposeToReduxDevtools(store); 48 exposeToReduxDevtools(store).catch((err) => {
49 log.error('Cannot initialize redux devtools', err);
50 });
46} 51}
47 52
48function Root(): JSX.Element { 53function Root(): JSX.Element {
diff --git a/packages/renderer/src/stores/RendererEnv.ts b/packages/renderer/src/stores/RendererEnv.ts
index d687738..f0a5a51 100644
--- a/packages/renderer/src/stores/RendererEnv.ts
+++ b/packages/renderer/src/stores/RendererEnv.ts
@@ -18,10 +18,10 @@
18 * SPDX-License-Identifier: AGPL-3.0-only 18 * SPDX-License-Identifier: AGPL-3.0-only
19 */ 19 */
20 20
21import { getEnv as getAnyEnv, IAnyStateTreeNode } from 'mobx-state-tree';
22import type { Action } from '@sophie/shared'; 21import type { Action } from '@sophie/shared';
22import { getEnv as getAnyEnv, IAnyStateTreeNode } from 'mobx-state-tree';
23 23
24export interface RendererEnv { 24export default interface RendererEnv {
25 dispatchMainAction(action: Action): void; 25 dispatchMainAction(action: Action): void;
26} 26}
27 27
diff --git a/packages/renderer/src/stores/RendererStore.ts b/packages/renderer/src/stores/RendererStore.ts
index 037b212..e684759 100644
--- a/packages/renderer/src/stores/RendererStore.ts
+++ b/packages/renderer/src/stores/RendererStore.ts
@@ -19,19 +19,24 @@
19 */ 19 */
20 20
21import { 21import {
22 applySnapshot,
23 applyPatch,
24 Instance,
25 types,
26} from 'mobx-state-tree';
27import {
28 BrowserViewBounds, 22 BrowserViewBounds,
29 sharedStore, 23 sharedStore,
30 SophieRenderer, 24 SophieRenderer,
31 ThemeSource, 25 ThemeSource,
32} from '@sophie/shared'; 26} from '@sophie/shared';
27import {
28 applySnapshot,
29 applyPatch,
30 Instance,
31 types,
32} from 'mobx-state-tree';
33
34import { getLogger } from '../utils/log';
35
36import type RendererEnv from './RendererEnv';
37import { getEnv } from './RendererEnv';
33 38
34import { getEnv, RendererEnv } from './RendererEnv'; 39const log = getLogger('RendererStore');
35 40
36export const rendererStore = types.model('RendererStore', { 41export const rendererStore = types.model('RendererStore', {
37 shared: types.optional(sharedStore, {}), 42 shared: types.optional(sharedStore, {}),
@@ -81,7 +86,7 @@ export function createAndConnectRendererStore(ipc: SophieRenderer): RendererStor
81 applyPatch(store.shared, patch); 86 applyPatch(store.shared, patch);
82 }, 87 },
83 }).catch((err) => { 88 }).catch((err) => {
84 console.error('Failed to connect to shared store', err); 89 log.error('Failed to connect to shared store', err);
85 }); 90 });
86 91
87 return store; 92 return store;
diff --git a/packages/renderer/src/utils/log.ts b/packages/renderer/src/utils/log.ts
new file mode 100644
index 0000000..c17fc2a
--- /dev/null
+++ b/packages/renderer/src/utils/log.ts
@@ -0,0 +1,50 @@
1/*
2 * Copyright (C) 2022 Kristóf Marussy <kristof@marussy.com>
3 *
4 * This file is part of Sophie.
5 *
6 * Sophie is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as
8 * published by the Free Software Foundation, version 3.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 *
18 * SPDX-License-Identifier: AGPL-3.0-only
19 */
20
21import loglevel, { Logger } from 'loglevel';
22import prefix from 'loglevel-plugin-prefix';
23
24if (import.meta.env?.DEV) {
25 loglevel.setLevel('debug');
26} else {
27 // No devtools in production, so there's not point to log anything.
28 loglevel.disableAll();
29}
30
31prefix.reg(loglevel);
32prefix.apply(loglevel, {
33 format(level, name, timestamp) {
34 const timeStr = timestamp.toString();
35 const nameStr = typeof name === 'undefined' ? '' : ` ${name}`;
36 return `[${timeStr}] ${level}${nameStr}:`;
37 },
38});
39
40export function getLogger(loggerName: string): Logger {
41 return loglevel.getLogger(loggerName);
42}
43
44export function silenceLogger(): void {
45 loglevel.disableAll();
46 const loggers = loglevel.getLoggers();
47 Object.keys(loggers).forEach((loggerName) => {
48 loggers[loggerName].disableAll();
49 });
50}