Browse Source

add light mode (#2223)

pull/2225/head
Jason Dove 1 year ago committed by GitHub
parent
commit
e0175fc4e5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      CHANGELOG.md
  2. 1
      ErsatzTV.Core/Domain/ConfigElementKey.cs
  3. 6
      ErsatzTV/Pages/Artist.razor
  4. 6
      ErsatzTV/Pages/Movie.razor
  5. 6
      ErsatzTV/Pages/TelevisionEpisodeList.razor
  6. 6
      ErsatzTV/Pages/TelevisionSeasonList.razor
  7. 2
      ErsatzTV/Pages/_Host.cshtml
  8. 50
      ErsatzTV/Shared/MainLayout.razor
  9. 31
      ErsatzTV/wwwroot/css/site.css

1
CHANGELOG.md

@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). @@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Sidecar text subtitles (e.g. `srt` files)
- Embedded image subtitles
- Embedded text subtitles that have already been extracted by ETV
- Add light mode and light/dark mode toggle to app bar
### Fixed
- Fix app startup with MySql/MariaDB

1
ErsatzTV.Core/Domain/ConfigElementKey.cs

@ -28,6 +28,7 @@ public class ConfigElementKey @@ -28,6 +28,7 @@ public class ConfigElementKey
public static ConfigElementKey SearchIndexVersion => new("search_index.version");
public static ConfigElementKey HDHRTunerCount => new("hdhr.tuner_count");
public static ConfigElementKey HDHRUUID => new("hdhr.uuid");
public static ConfigElementKey PagesIsDarkMode => new("pages.is_dark_mode");
public static ConfigElementKey ChannelsPageSize => new("pages.channels.page_size");
public static ConfigElementKey CollectionsPageSize => new("pages.collections.page_size");
public static ConfigElementKey MultiCollectionsPageSize => new("pages.multi_collections.page_size");

6
ErsatzTV/Pages/Artist.razor

@ -19,13 +19,13 @@ @@ -19,13 +19,13 @@
<img src="@($"artwork/fanart/{_artist.FanArt}")" alt="fan art"/>
}
</MudContainer>
<MudContainer MaxWidth="MaxWidth.Large" Style="margin-top: 100px">
<MudContainer MaxWidth="MaxWidth.Large" Style="margin-top: 100px" Class="z-10">
<MudStack Row="true" Breakpoint="Breakpoint.SmAndDown" Spacing="6">
@if (!string.IsNullOrWhiteSpace(_artist.Thumbnail))
{
<MudImage Elevation="2" Src="@($"artwork/thumbnails/{_artist.Thumbnail}")" Class="rounded-lg" Style="height: 220px; width: 220px; margin-left: auto; margin-right: auto;" />
<MudImage Elevation="2" Src="@($"artwork/thumbnails/{_artist.Thumbnail}")" Class="rounded-lg z-10" Style="height: 220px; width: 220px; margin-left: auto; margin-right: auto;" />
}
<div style="display: flex; flex-direction: column; height: 100%">
<div style="display: flex; flex-direction: column; height: 100%" class="z-10">
<MudStack Row="false">
<MudHidden Invert="true" Breakpoint="Breakpoint.SmAndDown">
<MudText Typo="Typo.h4" Class="media-item-title">@_artist?.Name</MudText>

6
ErsatzTV/Pages/Movie.razor

@ -27,11 +27,11 @@ @@ -27,11 +27,11 @@
}
}
</MudContainer>
<MudContainer MaxWidth="MaxWidth.Large" Style="margin-top: 100px">
<MudContainer MaxWidth="MaxWidth.Large" Style="margin-top: 100px" Class="z-10">
<MudStack Row="true" Breakpoint="Breakpoint.SmAndDown" Spacing="6">
@if (!string.IsNullOrWhiteSpace(_movie?.Poster))
{
<div style="display: flex; flex-direction: column; max-height: 325px; position: relative">
<div style="display: flex; flex-direction: column; max-height: 325px; position: relative" class="z-10">
<MudImage Src="@GetPosterUrl(_movie.Poster)" Elevation="2" Class="rounded-lg" Style="max-height: 325px; margin-left: auto; margin-right: auto" />
@if (_movie.MediaItemState == MediaItemState.FileNotFound)
{
@ -47,7 +47,7 @@ @@ -47,7 +47,7 @@
}
</div>
}
<div style="display: flex; flex-direction: column; height: 100%">
<div style="display: flex; flex-direction: column; height: 100%" class="z-10">
<MudStack Row="false">
<MudHidden Invert="true" Breakpoint="Breakpoint.SmAndDown">
<MudText Typo="Typo.h4" Class="media-item-title">@_movie?.Title</MudText>

6
ErsatzTV/Pages/TelevisionEpisodeList.razor

@ -27,13 +27,13 @@ @@ -27,13 +27,13 @@
}
}
</MudContainer>
<MudContainer MaxWidth="MaxWidth.Large" Style="margin-top: 100px">
<MudContainer MaxWidth="MaxWidth.Large" Style="margin-top: 100px" Class="z-10">
<MudStack Row="true" Breakpoint="Breakpoint.SmAndDown" Spacing="6">
@if (!string.IsNullOrWhiteSpace(_season?.Poster))
{
<MudImage Src="@GetPosterUrl(_season.Poster)" Elevation="2" Class="rounded-lg" Style="max-height: 325px; margin-left: auto; margin-right: auto"/>
<MudImage Src="@GetPosterUrl(_season.Poster)" Elevation="2" Class="rounded-lg z-10" Style="max-height: 325px; margin-left: auto; margin-right: auto"/>
}
<MudStack Row="false" Style="flex: 1">
<MudStack Row="false" Style="flex: 1" Class="z-10">
<MudStack Row="false">
<MudLink Href="@($"media/tv/shows/{_season?.ShowId}")">
<MudHidden Invert="true" Breakpoint="Breakpoint.SmAndDown">

6
ErsatzTV/Pages/TelevisionSeasonList.razor

@ -26,10 +26,10 @@ @@ -26,10 +26,10 @@
}
}
</MudContainer>
<MudContainer MaxWidth="MaxWidth.Large" Style="margin-top: 100px">
<MudContainer MaxWidth="MaxWidth.Large" Style="margin-top: 100px" Class="z-10">
<MudStack Row="true" Breakpoint="Breakpoint.SmAndDown" Spacing="6">
<MudImage Src="@GetPosterUrl(_show.Poster)" Elevation="2" Class="rounded-lg" Style="max-height: 325px; margin-left: auto; margin-right: auto" />
<MudStack Row="false" Style="flex: 1">
<MudImage Src="@GetPosterUrl(_show.Poster)" Elevation="2" Class="rounded-lg z-10" Style="max-height: 325px; margin-left: auto; margin-right: auto" />
<MudStack Row="false" Style="flex: 1" Class="z-10">
<MudStack Row="false">
<MudHidden Invert="true" Breakpoint="Breakpoint.SmAndDown">
<MudText Typo="Typo.h4" Class="media-item-title">@_show?.Title</MudText>

2
ErsatzTV/Pages/_Host.cshtml

@ -19,7 +19,7 @@ @@ -19,7 +19,7 @@
<link href="_content/MudBlazor/MudBlazor.min.css?v=@(Assembly.GetAssembly(typeof(AbstractLocalizationInterceptor))?.GetName().Version?.ToString())" rel="stylesheet"/>
<link href="css/site.css" asp-append-version="true" rel="stylesheet"/>
<link href="ErsatzTV.styles.css" asp-append-version="true" rel="stylesheet"/>
<link href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet">
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script type="module" src="https://cdn.jsdelivr.net/npm/media-chrome@1/+esm"></script>

50
ErsatzTV/Shared/MainLayout.razor

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
@inherits LayoutComponentBase
@using System.Reflection
@using ErsatzTV.Application.Configuration
@using ErsatzTV.Application.Search
@using ErsatzTV.Core.Health
@using ErsatzTV.Core.Interfaces.Search
@ -13,12 +14,12 @@ @@ -13,12 +14,12 @@
@inject ICourier Courier
@inject IHealthCheckService HealthCheckService;
<MudThemeProvider Theme="ErsatzTvTheme"/>
<MudThemeProvider Theme="ErsatzTvTheme" IsDarkMode="_isDarkMode"/>
<MudDialogProvider BackdropClick="false"/>
<MudSnackbarProvider/>
<MudPopoverProvider/>
<MudLayout @onclick="@(() => _isOpen = false)" Class="d-flex d-flex-column" Style="height: 100vh">
<MudLayout @onclick="@(() => _isOpen = false)" Class="@(_isDarkMode ? "d-flex d-flex-column ersatztv-dark" : "d-flex d-flex-column ersatztv-light")" Style="height: 100vh">
<MudAppBar Elevation="1" Class="app-bar">
<MudIconButton Icon="@Icons.Material.Filled.Menu" Color="Color.Inherit" Edge="Edge.Start" OnClick="@ToggleDrawer"/>
<div style="min-width: 240px" class="ml-3 d-none d-md-flex">
@ -92,6 +93,7 @@ @@ -92,6 +93,7 @@
<MudTooltip Text="GitHub">
<MudIconButton Icon="@Icons.Custom.Brands.GitHub" Color="Color.Primary" Href="https://github.com/ErsatzTV/ErsatzTV" Target="_blank"/>
</MudTooltip>
<MudIconButton Icon="@(DarkLightModeButtonIcon)" Color="Color.Primary" OnClick="@DarkModeToggle" />
<AuthorizeView>
<form action="/account/logout" method="post">
<MudTooltip Text="Logout">
@ -225,6 +227,7 @@ @@ -225,6 +227,7 @@
private List<SearchTargetViewModel> _searchTargets;
private int _errors;
private int _warnings;
private bool _isDarkMode = true;
protected override void OnInitialized()
{
@ -242,6 +245,18 @@ @@ -242,6 +245,18 @@
await HandleHealthCheckSummary(HealthCheckService.GetHealthCheckSummary(), CancellationToken.None);
}
private async Task DarkModeToggle()
{
_isDarkMode = !_isDarkMode;
await Mediator.Send(new SaveConfigElementByKey(ConfigElementKey.PagesIsDarkMode, _isDarkMode.ToString()));
}
public string DarkLightModeButtonIcon => _isDarkMode switch
{
true => Icons.Material.Rounded.DarkMode,
false => Icons.Material.Outlined.LightMode,
};
public void Dispose()
{
SystemStartup.OnDatabaseReady -= OnStartupProgress;
@ -257,7 +272,7 @@ @@ -257,7 +272,7 @@
private static MudTheme ErsatzTvTheme => new()
{
PaletteLight = new PaletteLight
PaletteDark = new PaletteDark
{
ActionDefault = "rgba(255,255,255, 0.80)",
Primary = "#009000",
@ -269,7 +284,8 @@ @@ -269,7 +284,8 @@
DrawerText = "rgba(255,255,255, 0.80)",
Divider = "rgba(255,255,255, 0.40)",
Background = "#272727",
TextPrimary = "rgba(255,255,255, 0.80)",
BackgroundGray = "#272727",
TextPrimary = "rgba(255,255,255, 0.90)",
TextSecondary = "rgba(255,255,255, 0.80)",
TextDisabled = "rgba(255,255,255, 0.40)",
ActionDisabled = "rgba(255,255,255, 0.40)",
@ -278,6 +294,28 @@ @@ -278,6 +294,28 @@
Info = "#00c0c0",
Tertiary = "#00c000",
White = Colors.Shades.White
},
PaletteLight = new PaletteLight
{
ActionDefault = "#546E7A",
Primary = "#546E7A",
Secondary = "#EC407A",
AppbarBackground = "#ECEFF1",
AppbarText = "#424242",
DrawerBackground = "#FFFFFF",
DrawerText = "#424242",
Surface = "#FFFFFF",
Background = "#F5F5F5",
TextPrimary = "#212121",
TextSecondary = "rgba(0,0,0, 0.7)",
TextDisabled = "rgba(0,0,0, 0.5)",
ActionDisabled = "rgba(0,0,0, 0.3)",
Divider = "rgba(0,0,0, 0.12)",
TableHover = "rgba(0,0,0, 0.02)",
TableLines = "rgba(0,0,0,0.08)",
Info = "#00c0c0",
Tertiary = "#00c000"
}
};
@ -318,6 +356,10 @@ @@ -318,6 +356,10 @@
{
_searchTargets = await Mediator.Send(new QuerySearchTargets(), _cts.Token);
}
_isDarkMode = await Mediator.Send(new GetConfigElementByKey(ConfigElementKey.PagesIsDarkMode), _cts.Token)
.MapT(result => !bool.TryParse(result.Value, out bool value) || value)
.IfNoneAsync(true);
}
protected async void OnSearchTargetsChanged(object sender, EventArgs e) => _searchTargets = await Mediator.Send(new QuerySearchTargets(), _cts.Token);

31
ErsatzTV/wwwroot/css/site.css

@ -1,4 +1,18 @@ @@ -1,4 +1,18 @@
.media-card-grid {
div.ersatztv-dark {
--fanart-background-rgb: 39, 39, 39;
--search-bar-background: rgba(255, 255, 255, .15);
--search-bar-text-color: #fafafa;
--selected-row-color: #009000;
}
div.ersatztv-light {
--fanart-background-rgb: 245, 245, 245;
--search-bar-background: #fff;
--search-bar-text-color: #424242;
--selected-row-color: #546E7A77;
}
.media-card-grid {
display: flex;
flex-direction: row;
flex-wrap: wrap;
@ -52,13 +66,13 @@ @@ -52,13 +66,13 @@
.search-bar .mud-input { height: 42px; }
.search-bar {
background-color: rgba(255, 255, 255, .15);
background-color: var(--search-bar-background);
border-radius: 4px;
height: 42px;
margin-bottom: 5px;
}
.search-bar div .mud-input-root { color: #fafafa; }
.search-bar div .mud-input-root { color: var(--search-bar-text-color); }
.search-bar .mud-input.mud-input-outlined .mud-input-outlined-border {
border: none;
@ -70,7 +84,7 @@ @@ -70,7 +84,7 @@
.fanart-container {
position: relative;
width: 100%;
z-index: -1;
z-index: 0;
}
.fanart-container img {
@ -83,7 +97,7 @@ @@ -83,7 +97,7 @@
}
.fanart-container > .fanart-tint {
background: linear-gradient(rgba(39, 39, 39, 0.47) 0%, rgb(39, 39, 39) 100%);
background: linear-gradient(rgba(var(--fanart-background-rgb), 0.47) 0%, rgb(var(--fanart-background-rgb)) 100%);
height: 400px;
position: absolute;
width: 100%;
@ -148,11 +162,6 @@ @@ -148,11 +162,6 @@
font-weight: unset;
}
.form-field-stack .mud-typography,
.mud-form .mud-typography-h5 {
color: rgba(255, 255, 255, 0.90);
}
.form-field-stack > div.d-flex {
width: 300px;
justify-content: flex-start;
@ -168,5 +177,5 @@ @@ -168,5 +177,5 @@
}
.selected {
background-color: #009000 !important;
background-color: var(--selected-row-color) !important;
}

Loading…
Cancel
Save