Closed simonv3 closed 2 years ago
I'm getting these errors:
ERROR in src/components/Profile.tsx:58:37
TS2339: Property 'darkMode' does not exist on type 'Window & typeof globalThis'.
56 | }, [fetchStats]);
57 | const toggleDarkMode = async () => {
> 58 | const isDarkMode = await window.darkMode.toggle()
| ^^^^^^^^
59 | if (
60 | document
61 | && document.getElementById('theme-source') !== null
ERROR in src/components/Profile.tsx:62:25
TS2531: Object is possibly 'null'.
60 | document
61 | && document.getElementById('theme-source') !== null
> 62 | && 'innerHTML' in document.getElementById('theme-source')
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
63 | ) {
64 | document.getElementById('theme-source').innerHTML = isDarkMode ? 'Dark' : 'Light'
65 | }
ERROR in src/components/Profile.tsx:64:7
TS2531: Object is possibly 'null'.
62 | && 'innerHTML' in document.getElementById('theme-source')
63 | ) {
> 64 | document.getElementById('theme-source').innerHTML = isDarkMode ? 'Dark' : 'Light'
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
65 | }
66 | }
67 |
ERROR in src/components/Profile.tsx:69:18
TS2339: Property 'darkMode' does not exist on type 'Window & typeof globalThis'.
67 |
68 | const resetToSystem = async () => {
> 69 | await window.darkMode.system()
| ^^^^^^^^
70 | if (
71 | document
72 | && document.getElementById('theme-source') !== null
ERROR in src/components/Profile.tsx:73:25
TS2531: Object is possibly 'null'.
71 | document
72 | && document.getElementById('theme-source') !== null
> 73 | && 'innerHTML' in document.getElementById('theme-source')
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
74 | ) {
75 | document.getElementById('theme-source').innerHTML = 'System'
76 | }
ERROR in src/components/Profile.tsx:75:7
TS2531: Object is possibly 'null'.
73 | && 'innerHTML' in document.getElementById('theme-source')
74 | ) {
> 75 | document.getElementById('theme-source').innerHTML = 'System'
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
76 | }
77 | }
78 |
With this diff:
diff --git a/public/electron.js b/public/electron.js
index c6d5274..276bbf5 100644
--- a/public/electron.js
+++ b/public/electron.js
@@ -1,5 +1,5 @@
// Module to control the application lifecycle and the native browser window.
-const { app, BrowserWindow, protocol, shell } = require("electron");
+const { app, BrowserWindow, nativeTheme, ipcMain, protocol, shell } = require("electron");
const path = require("path");
// Create the native browser window.
@@ -28,6 +28,20 @@ function createWindow() {
if (!app.isPackaged) {
mainWindow.webContents.openDevTools();
}
+
+ // Dark mode
+ ipcMain.handle('dark-mode:toggle', () => {
+ if (nativeTheme.shouldUseDarkColors) {
+ nativeTheme.themeSource = 'light'
+ } else {
+ nativeTheme.themeSource = 'dark'
+ }
+ return nativeTheme.shouldUseDarkColors
+ })
+
+ ipcMain.handle('dark-mode:system', () => {
+ nativeTheme.themeSource = 'system'
+ })
}
// Setup a local proxy to adjust the paths of requested files when loading
diff --git a/public/preload.js b/public/preload.js
index bd020c8..a2ef178 100644
--- a/public/preload.js
+++ b/public/preload.js
@@ -1,10 +1,15 @@
// All of the Node.js APIs are available in the preload process.
// It has the same sandbox as a Chrome extension.
-const { contextBridge } = require("electron");
+const { contextBridge, ipcRenderer } = require("electron");
// As an example, here we use the exposeInMainWorld API to expose the browsers
// and node versions to the main window.
// They'll be accessible at "window.versions".
process.once("loaded", () => {
contextBridge.exposeInMainWorld("versions", process.versions);
+
+ contextBridge.exposeInMainWorld('darkMode', {
+ toggle: () => ipcRenderer.invoke('dark-mode:toggle'),
+ system: () => ipcRenderer.invoke('dark-mode:system')
+ })
});
diff --git a/src/components/Profile.tsx b/src/components/Profile.tsx
index 65907d0..f224d08 100644
--- a/src/components/Profile.tsx
+++ b/src/components/Profile.tsx
@@ -54,6 +54,28 @@ const Profile: React.FC = () => {
React.useEffect(() => {
fetchStats();
}, [fetchStats]);
+ const toggleDarkMode = async () => {
+ const isDarkMode = await window.darkMode.toggle()
+ if (
+ document
+ && document.getElementById('theme-source') !== null
+ && 'innerHTML' in document.getElementById('theme-source')
+ ) {
+ document.getElementById('theme-source').innerHTML = isDarkMode ? 'Dark' : 'Light'
+ }
+ }
+
+ const resetToSystem = async () => {
+ await window.darkMode.system()
+ if (
+ document
+ && document.getElementById('theme-source') !== null
+ && 'innerHTML' in document.getElementById('theme-source')
+ ) {
+ document.getElementById('theme-source').innerHTML = 'System'
+ }
+ }
+
return (
<div
@@ -62,6 +84,8 @@ const Profile: React.FC = () => {
max-width: 820px;
`}
>
+ <Button onClick={toggleDarkMode}>Toggle Dark Mode</Button>
+ <Button onClick={resetToSystem}>Reset to System Theme</Button>
{user && (
<div
className={css`
diff --git a/src/index.css b/src/index.css
index ec2585e..322a402 100644
--- a/src/index.css
+++ b/src/index.css
@@ -11,3 +11,11 @@ code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}
+
+@media (prefers-color-scheme: dark) {
+ body { background: #333; color: white; }
+}
+
+@media (prefers-color-scheme: light) {
+ body { background: #ddd; color: black; }
+}
Seems like public/preload.js
isn't making darkMode
available on the main window, the way I have this set up in the above diff.
@peterklingelhofer do you have a branch I could test on? Are these errors happening when running the app inside electron with yarn electron:start
or just with yarn start
@simonv3 here is the branch
These errors are happening with good ol' yarn start
Ah that makes sense, I don't think electron library is available like that in the normal web view, which is what yarn start
does (it's just the normal react-script start
reference). If beam were to be deployed on a server, we'd have to figure out a way to do this without referencing the electron package. I actually wonder, is there no way for the browser to detect this without having electron supplying it?
Ack, yeah that's tricky in case we want this to potentially eventually replace the web player as well.
Also, that's silly that pulling from upstream from the GitHub website defaults to merging, should definitely be a rebase... I'll fix this branch later to cleanup that commit history. EDIT: Done!
this could be a toggle on the
/profile
page, but could also inherit from the user's settings on their computerhttps://www.electronjs.org/docs/v14-x-y/tutorial/dark-mode