Browse Source

use full preferred language names in ui (#137)

pull/138/head v0.0.29-prealpha
Jason Dove 4 years ago committed by GitHub
parent
commit
efae005447
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      ErsatzTV.Application/MediaItems/Queries/GetAllLanguageCodes.cs
  2. 35
      ErsatzTV.Application/MediaItems/Queries/GetAllLanguageCodesHandler.cs
  3. 1
      ErsatzTV.Core/Interfaces/Repositories/IMediaItemRepository.cs
  4. 19
      ErsatzTV.Infrastructure/Data/Repositories/MediaItemRepository.cs
  5. 12
      ErsatzTV/Pages/ChannelEditor.razor
  6. 23
      ErsatzTV/Pages/Channels.razor
  7. 27
      ErsatzTV/Pages/FFmpeg.razor

8
ErsatzTV.Application/MediaItems/Queries/GetAllLanguageCodes.cs

@ -0,0 +1,8 @@
using System.Collections.Generic;
using System.Globalization;
using MediatR;
namespace ErsatzTV.Application.MediaItems.Queries
{
public record GetAllLanguageCodes : IRequest<List<CultureInfo>>;
}

35
ErsatzTV.Application/MediaItems/Queries/GetAllLanguageCodesHandler.cs

@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Threading;
using System.Threading.Tasks;
using ErsatzTV.Core.Interfaces.Repositories;
using LanguageExt;
using MediatR;
namespace ErsatzTV.Application.MediaItems.Queries
{
public class GetAllLanguageCodesHandler : IRequestHandler<GetAllLanguageCodes, List<CultureInfo>>
{
private readonly IMediaItemRepository _mediaItemRepository;
public GetAllLanguageCodesHandler(IMediaItemRepository mediaItemRepository) =>
_mediaItemRepository = mediaItemRepository;
public async Task<List<CultureInfo>> Handle(GetAllLanguageCodes request, CancellationToken cancellationToken)
{
var result = new List<CultureInfo>();
CultureInfo[] allCultures = CultureInfo.GetCultures(CultureTypes.AllCultures);
List<string> allLanguageCodes = await _mediaItemRepository.GetAllLanguageCodes();
foreach (string code in allLanguageCodes)
{
Option<CultureInfo> maybeCulture = allCultures.Find(
ci => string.Equals(code, ci.ThreeLetterISOLanguageName, StringComparison.OrdinalIgnoreCase));
await maybeCulture.IfSomeAsync(cultureInfo => result.Add(cultureInfo));
}
return result;
}
}
}

1
ErsatzTV.Core/Interfaces/Repositories/IMediaItemRepository.cs

@ -10,5 +10,6 @@ namespace ErsatzTV.Core.Interfaces.Repositories
Task<Option<MediaItem>> Get(int id); Task<Option<MediaItem>> Get(int id);
Task<List<MediaItem>> GetAll(); Task<List<MediaItem>> GetAll();
Task<bool> Update(MediaItem mediaItem); Task<bool> Update(MediaItem mediaItem);
Task<List<string>> GetAllLanguageCodes();
} }
} }

19
ErsatzTV.Infrastructure/Data/Repositories/MediaItemRepository.cs

@ -1,6 +1,8 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Data;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Dapper;
using ErsatzTV.Core.Domain; using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Interfaces.Repositories; using ErsatzTV.Core.Interfaces.Repositories;
using LanguageExt; using LanguageExt;
@ -11,10 +13,14 @@ namespace ErsatzTV.Infrastructure.Data.Repositories
{ {
public class MediaItemRepository : IMediaItemRepository public class MediaItemRepository : IMediaItemRepository
{ {
private readonly IDbConnection _dbConnection;
private readonly IDbContextFactory<TvContext> _dbContextFactory; private readonly IDbContextFactory<TvContext> _dbContextFactory;
public MediaItemRepository(IDbContextFactory<TvContext> dbContextFactory) => public MediaItemRepository(IDbContextFactory<TvContext> dbContextFactory, IDbConnection dbConnection)
{
_dbContextFactory = dbContextFactory; _dbContextFactory = dbContextFactory;
_dbConnection = dbConnection;
}
public async Task<Option<MediaItem>> Get(int id) public async Task<Option<MediaItem>> Get(int id)
{ {
@ -38,5 +44,16 @@ namespace ErsatzTV.Infrastructure.Data.Repositories
context.MediaItems.Update(mediaItem); context.MediaItems.Update(mediaItem);
return await context.SaveChangesAsync() > 0; return await context.SaveChangesAsync() > 0;
} }
public Task<List<string>> GetAllLanguageCodes() =>
_dbConnection.QueryAsync<string>(
@"SELECT LanguageCode FROM
(SELECT Language AS LanguageCode
FROM MediaStream WHERE Language IS NOT NULL
UNION ALL SELECT PreferredLanguageCode AS LanguageCode
FROM Channel WHERE PreferredLanguageCode IS NOT NULL)
GROUP BY LanguageCode
ORDER BY COUNT(LanguageCode) DESC")
.Map(result => result.ToList());
} }
} }

12
ErsatzTV/Pages/ChannelEditor.razor

@ -4,6 +4,8 @@
@using ErsatzTV.Application.FFmpegProfiles @using ErsatzTV.Application.FFmpegProfiles
@using ErsatzTV.Application.FFmpegProfiles.Queries @using ErsatzTV.Application.FFmpegProfiles.Queries
@using ErsatzTV.Application.Images.Commands @using ErsatzTV.Application.Images.Commands
@using ErsatzTV.Application.MediaItems.Queries
@using System.Globalization
@using ErsatzTV.Application.Channels @using ErsatzTV.Application.Channels
@using ErsatzTV.Application.Channels.Queries @using ErsatzTV.Application.Channels.Queries
@inject NavigationManager NavigationManager @inject NavigationManager NavigationManager
@ -34,7 +36,13 @@
<MudSelectItem Value="@profile.Id">@profile.Name</MudSelectItem> <MudSelectItem Value="@profile.Id">@profile.Name</MudSelectItem>
} }
</MudSelect> </MudSelect>
<MudTextField Class="mt-3" Label="Preferred Language Code" @bind-Value="_model.PreferredLanguageCode" For="@(() => _model.PreferredLanguageCode)"/> <MudSelect Class="mt-3" Label="Preferred Language" @bind-Value="_model.PreferredLanguageCode" For="@(() => _model.PreferredLanguageCode)">
<MudSelectItem Value="@((string) null)">(none)</MudSelectItem>
@foreach (CultureInfo culture in _availableCultures)
{
<MudSelectItem Value="@culture.ThreeLetterISOLanguageName">@culture.EnglishName</MudSelectItem>
}
</MudSelect>
<MudGrid Class="mt-3" Style="align-items: center" Justify="Justify.Center"> <MudGrid Class="mt-3" Style="align-items: center" Justify="Justify.Center">
<MudItem xs="6"> <MudItem xs="6">
<InputFile id="fileInput" OnChange="UploadLogo" hidden/> <InputFile id="fileInput" OnChange="UploadLogo" hidden/>
@ -74,10 +82,12 @@
private ValidationMessageStore _messageStore; private ValidationMessageStore _messageStore;
private List<FFmpegProfileViewModel> _ffmpegProfiles; private List<FFmpegProfileViewModel> _ffmpegProfiles;
private List<CultureInfo> _availableCultures;
protected override async Task OnParametersSetAsync() protected override async Task OnParametersSetAsync()
{ {
await LoadFFmpegProfilesAsync(); await LoadFFmpegProfilesAsync();
_availableCultures = await Mediator.Send(new GetAllLanguageCodes());
if (Id.HasValue) if (Id.HasValue)
{ {

23
ErsatzTV/Pages/Channels.razor

@ -4,6 +4,7 @@
@using ErsatzTV.Application.Channels.Queries @using ErsatzTV.Application.Channels.Queries
@using ErsatzTV.Application.FFmpegProfiles @using ErsatzTV.Application.FFmpegProfiles
@using ErsatzTV.Application.FFmpegProfiles.Queries @using ErsatzTV.Application.FFmpegProfiles.Queries
@using System.Globalization
@inject IDialogService Dialog @inject IDialogService Dialog
@inject IMediator Mediator @inject IMediator Mediator
@ -99,7 +100,25 @@
} }
} }
private async Task LoadChannelsAsync() => _channels = await Mediator.Send(new GetAllChannels()) private async Task LoadChannelsAsync()
.Map(list => list.OrderBy(c => decimal.Parse(c.Number)).ToList()); {
List<ChannelViewModel> channels = await Mediator.Send(new GetAllChannels());
IOrderedEnumerable<ChannelViewModel> sorted = channels.OrderBy(c => decimal.Parse(c.Number));
CultureInfo[] allCultures = CultureInfo.GetCultures(CultureTypes.NeutralCultures);
_channels = new List<ChannelViewModel>();
foreach (ChannelViewModel channel in sorted)
{
Option<CultureInfo> maybeCultureInfo = allCultures.Find(
ci => string.Equals(
ci.ThreeLetterISOLanguageName,
channel.PreferredLanguageCode,
StringComparison.OrdinalIgnoreCase));
maybeCultureInfo.Match(
cultureInfo => _channels.Add(channel with { PreferredLanguageCode = cultureInfo.EnglishName }),
() => _channels.Add(channel));
}
}
} }

27
ErsatzTV/Pages/FFmpeg.razor

@ -2,8 +2,9 @@
@using ErsatzTV.Application.FFmpegProfiles @using ErsatzTV.Application.FFmpegProfiles
@using ErsatzTV.Application.FFmpegProfiles.Commands @using ErsatzTV.Application.FFmpegProfiles.Commands
@using ErsatzTV.Application.FFmpegProfiles.Queries @using ErsatzTV.Application.FFmpegProfiles.Queries
@using Unit = LanguageExt.Unit @using ErsatzTV.Application.MediaItems.Queries
@using System.Globalization @using System.Globalization
@using Unit = LanguageExt.Unit
@inject IDialogService Dialog @inject IDialogService Dialog
@inject IMediator Mediator @inject IMediator Mediator
@inject ILogger<FFmpeg> Logger @inject ILogger<FFmpeg> Logger
@ -30,9 +31,12 @@
} }
</MudSelect> </MudSelect>
</MudElement> </MudElement>
<MudElement HtmlTag="div" Class="mt-3"> <MudSelect Class="mt-3" Label="Preferred Language" @bind-Value="_ffmpegSettings.PreferredLanguageCode" For="@(() => _ffmpegSettings.PreferredLanguageCode)" Required="true" RequiredError="Preferred Language Code is required!">
<MudTextField T="string" Label="Preferred Language Code" @bind-Value="_ffmpegSettings.PreferredLanguageCode" Validation="@(new Func<string, string>(ValidateLanguageCode))" Required="true" RequiredError="Preferred Language Code is required!"/> @foreach (CultureInfo culture in _availableCultures)
</MudElement> {
<MudSelectItem Value="@culture.ThreeLetterISOLanguageName">@culture.EnglishName</MudSelectItem>
}
</MudSelect>
<MudElement HtmlTag="div" Class="mt-3"> <MudElement HtmlTag="div" Class="mt-3">
<MudSwitch T="bool" <MudSwitch T="bool"
Label="Save troubleshooting reports to disk" Label="Save troubleshooting reports to disk"
@ -115,12 +119,14 @@
private FFmpegSettingsViewModel _ffmpegSettings; private FFmpegSettingsViewModel _ffmpegSettings;
private List<FFmpegProfileViewModel> _ffmpegProfiles; private List<FFmpegProfileViewModel> _ffmpegProfiles;
private List<CultureInfo> _availableCultures;
protected override async Task OnParametersSetAsync() protected override async Task OnParametersSetAsync()
{ {
_ffmpegSettings = await Mediator.Send(new GetFFmpegSettings()); _ffmpegSettings = await Mediator.Send(new GetFFmpegSettings());
_success = File.Exists(_ffmpegSettings.FFmpegPath) && File.Exists(_ffmpegSettings.FFprobePath); _success = File.Exists(_ffmpegSettings.FFmpegPath) && File.Exists(_ffmpegSettings.FFprobePath);
await LoadFFmpegProfilesAsync(); await LoadFFmpegProfilesAsync();
_availableCultures = await Mediator.Send(new GetAllLanguageCodes());
} }
private async Task SaveSettings() private async Task SaveSettings()
@ -137,19 +143,6 @@
private static string ValidatePathExists(string path) => !File.Exists(path) ? "Path does not exist" : null; private static string ValidatePathExists(string path) => !File.Exists(path) ? "Path does not exist" : null;
private static string ValidateLanguageCode(string languageCode)
{
if (string.IsNullOrWhiteSpace(languageCode))
{
return null;
}
Option<CultureInfo> culture = CultureInfo.GetCultures(CultureTypes.NeutralCultures)
.FirstOrDefault(ci => string.Equals(ci.ThreeLetterISOLanguageName, languageCode, StringComparison.OrdinalIgnoreCase));
return culture.IsNone ? "Preferred language code is invalid" : null;
}
private async Task LoadFFmpegProfilesAsync() => private async Task LoadFFmpegProfilesAsync() =>
_ffmpegProfiles = await Mediator.Send(new GetAllFFmpegProfiles()); _ffmpegProfiles = await Mediator.Send(new GetAllFFmpegProfiles());

Loading…
Cancel
Save