Skip to content

Commit

Permalink
New: Dark theme for login screen
Browse files Browse the repository at this point in the history
Closes #6751
  • Loading branch information
markus101 committed May 9, 2024
1 parent f81bb3e commit cae134e
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 77 deletions.
9 changes: 4 additions & 5 deletions frontend/src/App/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@ function App({ store, history }) {
<DocumentTitle title={window.Sonarr.instanceName}>
<Provider store={store}>
<ConnectedRouter history={history}>
<ApplyTheme>
<PageConnector>
<AppRoutes app={App} />
</PageConnector>
</ApplyTheme>
<ApplyTheme />
<PageConnector>
<AppRoutes app={App} />
</PageConnector>
</ConnectedRouter>
</Provider>
</DocumentTitle>
Expand Down
50 changes: 0 additions & 50 deletions frontend/src/App/ApplyTheme.js

This file was deleted.

37 changes: 37 additions & 0 deletions frontend/src/App/ApplyTheme.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React, { Fragment, ReactNode, useCallback, useEffect } from 'react';
import { useSelector } from 'react-redux';
import { createSelector } from 'reselect';
import themes from 'Styles/Themes';
import AppState from './State/AppState';

interface ApplyThemeProps {
children: ReactNode;
}

function createThemeSelector() {
return createSelector(
(state: AppState) => state.settings.ui.item.theme || window.Sonarr.theme,
(theme) => {
return theme;
}
);
}

function ApplyTheme({ children }: ApplyThemeProps) {
const theme = useSelector(createThemeSelector());

const updateCSSVariables = useCallback(() => {
Object.entries(themes[theme]).forEach(([key, value]) => {
document.documentElement.style.setProperty(`--${key}`, value);
});
}, [theme]);

// On Component Mount and Component Update
useEffect(() => {
updateCSSVariables();
}, [updateCSSVariables, theme]);

return <Fragment>{children}</Fragment>;
}

export default ApplyTheme;
2 changes: 1 addition & 1 deletion frontend/src/Styles/Themes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as dark from './dark';
import * as light from './light';

const defaultDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
const auto = defaultDark ? { ...dark } : { ...light };
const auto = defaultDark ? dark : light;

export default {
auto,
Expand Down
93 changes: 74 additions & 19 deletions frontend/src/login.html
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@

<style>
body {
background-color: #f5f7fa;
color: #656565;
background-color: var(--pageBackground);
color: var(--textColor);
font-family: "Roboto", "open sans", "Helvetica Neue", Helvetica, Arial,
sans-serif;
}
Expand Down Expand Up @@ -88,14 +88,14 @@
padding: 10px;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
background-color: #3a3f51;
background-color: var(--themeDarkColor);
}

.panel-body {
padding: 20px;
border-bottom-right-radius: 4px;
border-bottom-left-radius: 4px;
background-color: #fff;
background-color: var(--panelBackground);
}

.sign-in {
Expand All @@ -112,16 +112,17 @@
padding: 6px 16px;
width: 100%;
height: 35px;
border: 1px solid #dde6e9;
background-color: var(--inputBackgroundColor);
border: 1px solid var(--inputBorderColor);
border-radius: 4px;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 1px 1px var(--inputBoxShadowColor);
}

.form-input:focus {
outline: 0;
border-color: #66afe9;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075),
0 0 8px rgba(102, 175, 233, 0.6);
border-color: var(--inputFocusBorderColor);
box-shadow: inset 0 1px 1px var(--inputBoxShadowColor),
0 0 8px var(--inputFocusBoxShadowColor);
}

.button {
Expand All @@ -130,20 +131,20 @@
padding: 10px 0;
width: 100%;
border: 1px solid;
border-color: #5899eb;
border-color: var(--primaryBorderColor);
border-radius: 4px;
background-color: #5d9cec;
color: #fff;
background-color: var(--primaryBackgroundColor);
color: var(--white);
vertical-align: middle;
text-align: center;
white-space: nowrap;
line-height: normal;
}

.button:hover {
border-color: #3483e7;
background-color: #4b91ea;
color: #fff;
border-color: var(--primaryHoverBorderColor);
background-color: var(--primaryHoverBackgroundColor);
color: var(--white);
text-decoration: none;
}

Expand All @@ -165,24 +166,24 @@

.forgot-password {
margin-left: auto;
color: #909fa7;
color: var(--forgotPasswordColor);
text-decoration: none;
font-size: 13px;
}

.forgot-password:focus,
.forgot-password:hover {
color: #748690;
color: var(--forgotPasswordAltColor);
text-decoration: underline;
}

.forgot-password:visited {
color: #748690;
color: var(--forgotPasswordAltColor);
}

.login-failed {
margin-top: 20px;
color: #f05050;
color: var(--failedColor);
font-size: 14px;
}

Expand Down Expand Up @@ -291,5 +292,59 @@

loginFailedDiv.classList.remove("hidden");
}

var light = {
white: '#fff',
pageBackground: '#f5f7fa',
textColor: '#656565',
themeDarkColor: '#3a3f51',
panelBackground: '#fff',
inputBackgroundColor: '#fff',
inputBorderColor: '#dde6e9',
inputBoxShadowColor: 'rgba(0, 0, 0, 0.075)',
inputFocusBorderColor: '#66afe9',
inputFocusBoxShadowColor: 'rgba(102, 175, 233, 0.6)',
primaryBackgroundColor: '#5d9cec',
primaryBorderColor: '#5899eb',
primaryHoverBackgroundColor: '#4b91ea',
primaryHoverBorderColor: '#3483e7',
failedColor: '#f05050',
forgotPasswordColor: '#909fa7',
forgotPasswordAltColor: '#748690'
};

var dark = {
white: '#fff',
pageBackground: '#202020',
textColor: '#656565',
themeDarkColor: '#494949',
panelBackground: '#111',
inputBackgroundColor: '#333',
inputBorderColor: '#dde6e9',
inputBoxShadowColor: 'rgba(0, 0, 0, 0.075)',
inputFocusBorderColor: '#66afe9',
inputFocusBoxShadowColor: 'rgba(102, 175, 233, 0.6)',
primaryBackgroundColor: '#5d9cec',
primaryBorderColor: '#5899eb',
primaryHoverBackgroundColor: '#4b91ea',
primaryHoverBorderColor: '#3483e7',
failedColor: '#f05050',
forgotPasswordColor: '#737d83',
forgotPasswordAltColor: '#546067'
};

var theme = "_THEME_";
var defaultDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
var finalTheme = theme === 'dark' || (theme === 'auto' && defaultDark) ?
dark :
light;

Object.entries(finalTheme).forEach(([key, value]) => {
document.documentElement.style.setProperty(
`--${key}`,
value
);
});

</script>
</html>
2 changes: 1 addition & 1 deletion frontend/src/typings/UiSettings.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export interface UiSettings {
theme: string;
theme: 'auto' | 'dark' | 'light';
showRelativeDates: boolean;
shortDateFormat: string;
longDateFormat: string;
Expand Down
2 changes: 1 addition & 1 deletion src/Sonarr.Http/Frontend/Mappers/HtmlMapperBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ protected override Stream GetContentStream(string filePath)
return stream;
}

protected string GetHtmlText()
protected virtual string GetHtmlText()
{
if (RuntimeInfo.IsProduction && _generatedContent != null)
{
Expand Down
13 changes: 13 additions & 0 deletions src/Sonarr.Http/Frontend/Mappers/LoginHtmlMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@ namespace Sonarr.Http.Frontend.Mappers
{
public class LoginHtmlMapper : HtmlMapperBase
{
private readonly IConfigFileProvider _configFileProvider;

public LoginHtmlMapper(IAppFolderInfo appFolderInfo,
IDiskProvider diskProvider,
Lazy<ICacheBreakerProvider> cacheBreakProviderFactory,
IConfigFileProvider configFileProvider,
Logger logger)
: base(diskProvider, cacheBreakProviderFactory, logger)
{
_configFileProvider = configFileProvider;
HtmlPath = Path.Combine(appFolderInfo.StartUpFolder, configFileProvider.UiFolder, "login.html");
UrlBase = configFileProvider.UrlBase;
}
Expand All @@ -29,5 +32,15 @@ public override bool CanHandle(string resourceUrl)
{
return resourceUrl.StartsWith("/login");
}

protected override string GetHtmlText()
{
var html = base.GetHtmlText();
var theme = _configFileProvider.Theme;

html = html.Replace("_THEME_", theme);

return html;
}
}
}

0 comments on commit cae134e

Please sign in to comment.