Change theme based on macOS settings (desktop)

This commit is contained in:
Marquis Kurt 2019-05-16 11:00:37 -04:00
parent d9c93db83e
commit 01bf4e9ac5
7 changed files with 53 additions and 7 deletions

View File

@ -76,7 +76,8 @@
"target": [
"dmg",
"mas"
]
],
"darkModeSupport": true
},
"mas": {
"entitlements": "desktop/entitlements.mas.plist",

View File

@ -2,7 +2,7 @@
// Electron script to run Hyperspace as an app
// © 2018 Hyperspace developers. Licensed under Apache 2.0.
const { app, Menu, protocol, BrowserWindow, shell } = require('electron');
const { app, Menu, protocol, BrowserWindow, shell, systemPreferences } = require('electron');
const windowStateKeeper = require('electron-window-state');
const { autoUpdater } = require('electron-updater');
const path = require('path');
@ -135,6 +135,11 @@ function createWindow() {
// Load the main app and open the index page.
mainWindow.loadURL("hyperspace://hyperspace/app/");
// Watch for a change in macOS's dark mode and reload the window to apply changes
systemPreferences.subscribeNotification('AppleInterfaceThemeChangedNotification', () => {
mainWindow.webContents.reload();
})
// Delete the window when closed
mainWindow.on('closed', () => {
mainWindow = null

View File

@ -21,6 +21,7 @@ import { Notification } from '../../types/Notification';
import {sendNotificationRequest} from '../../utilities/notifications';
import {withSnackbar} from 'notistack';
import { getConfig, getUserDefaultBool } from '../../utilities/settings';
import { isDarwinApp } from '../../utilities/desktop';
import { Config } from '../../types/Config';
interface IAppLayoutState {
@ -175,7 +176,7 @@ export class AppLayout extends Component<any, IAppLayoutState> {
titlebar() {
const { classes } = this.props;
if ((navigator.userAgent.includes(this.state.brandName || "Hyperspace") || navigator.userAgent.includes("Electron")) && navigator.userAgent.includes("Macintosh")) {
if (isDarwinApp()) {
return (
<div className={classes.titleBarRoot}>
<Typography className={classes.titleBarText}>{this.state.brandName? this.state.brandName: "Hyperspace"} {this.state.developerMode? "(beta)": null}</Typography>

View File

@ -28,7 +28,7 @@ import {setUserDefaultBool, getUserDefaultBool, getUserDefaultTheme, setUserDefa
import {canSendNotifications, browserSupportsNotificationRequests} from '../utilities/notifications';
import {themes, defaultTheme} from '../types/HyperspaceTheme';
import ThemePreview from '../components/ThemePreview';
import {setHyperspaceTheme, getHyperspaceTheme} from '../utilities/themes';
import {setHyperspaceTheme, getHyperspaceTheme, getDarkModeFromSystem} from '../utilities/themes';
import { Visibility } from '../types/Visibility';
import {LinkableButton} from '../interfaces/overrides';
@ -102,6 +102,7 @@ class SettingsPage extends Component<any, ISettingsState> {
console.error(err.message);
});
this.getFederatedStatus();
console.log(getDarkModeFromSystem());
}
getFederatedStatus() {

View File

@ -6,6 +6,7 @@ import {SaveClientSession} from '../types/SessionData';
import { createHyperspaceApp, getRedirectAddress } from '../utilities/login';
import {parseUrl} from 'query-string';
import { getConfig } from '../utilities/settings';
import { isDarwinApp } from '../utilities/desktop';
import axios from 'axios';
import {withSnackbar, withSnackbarProps} from 'notistack';
import { Config } from '../types/Config';
@ -63,7 +64,7 @@ class WelcomePage extends Component<IWelcomeProps, IWelcomeState> {
if (result !== undefined) {
let config: Config = result;
if (result.location === "dynamic") {
console.warn("Recirect URI is set to dyanmic, which may affect how sign-in works for some users. Careful!");
console.warn("Recirect URI is set to dynamic, which may affect how sign-in works for some users. Careful!");
}
this.setState({
logoUrl: config.branding? result.branding.logo: "logo.png",
@ -302,7 +303,7 @@ class WelcomePage extends Component<IWelcomeProps, IWelcomeState> {
titlebar() {
const { classes } = this.props;
if ((navigator.userAgent.includes(this.state.brandName || "Hyperspace") || navigator.userAgent.includes("Electron")) && navigator.userAgent.includes("Macintosh")) {
if (isDarwinApp()) {
return (
<div className={classes.titleBarRoot}>
<Typography className={classes.titleBarText}>{this.state.brandName? this.state.brandName: "Hyperspace"}</Typography>

32
src/utilities/desktop.tsx Normal file
View File

@ -0,0 +1,32 @@
/**
* A Window interface with extra properties for Electron
*/
interface ElectronWindow extends Window {
require?: any;
}
// Lift window to an ElectronWindow and add use require()
const eWin = window as ElectronWindow;
const {remote} = eWin.require('electron');
/**
* Determines whether the app is running from a website or an app.
* @returns Boolean of whether it is in desktop mode or not
*/
export function isDesktopApp(): boolean {
return navigator.userAgent.includes("Hyperspace" || "Electron");
}
/**
* Determines whether the app is the macOS application
*/
export function isDarwinApp(): boolean {
return isDesktopApp() && navigator.userAgent.includes("Macintosh")
}
/**
* Determine whether the system is in dark mode or not (macOS)
*/
export function isDarkMode() {
return remote.systemPreferences.isDarkMode()
}

View File

@ -1,6 +1,7 @@
import { createMuiTheme, Theme } from '@material-ui/core';
import { HyperspaceTheme, themes, defaultTheme } from '../types/HyperspaceTheme';
import { getUserDefaultBool } from './settings';
import { isDarwinApp, isDarkMode } from './desktop';
/**
* Locates a Hyperspace theme from the themes catalog
@ -53,7 +54,11 @@ export function getDarkModeFromSystem(): string {
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
return "dark";
} else {
return "light";
if (isDarwinApp()) {
return isDarkMode()? "dark": "light";
} else {
return "light";
}
}
} else {
return "light";