Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
using Windows.UI;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Media;

namespace JellyBox.Controls;

internal sealed partial class CustomMediaTransportControls
{
private static readonly SolidColorBrush FavoriteOnBrush = new(Colors.Red);
private static readonly SolidColorBrush FavoriteOffBrush = new(Colors.White);

private bool _isUpdatingVolumeSlider;

private void UpdatePlayPauseIcon() => _playPauseIcon?.Glyph = IsPlaying ? Glyphs.Pause : Glyphs.Play;

private void UpdateFavoriteIcon() => _favoriteIcon?.Glyph = IsFavorite ? Glyphs.HeartFilled : Glyphs.HeartOutline;
private void UpdateFavoriteIcon()
{
if (_favoriteIcon is null)
{
return;
}

_favoriteIcon.Glyph = IsFavorite ? Glyphs.HeartFilled : Glyphs.HeartOutline;
_favoriteIcon.Foreground = IsFavorite ? FavoriteOnBrush : FavoriteOffBrush;
}

private void UpdateEndsAtText() => _endsAtTextBlock?.Text = EndsAtText;

Expand Down
23 changes: 23 additions & 0 deletions src/JellyBox/Converters/BoolToBrushConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using Windows.UI;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Media;

namespace JellyBox.Converters;

/// <summary>
/// Value converter that translates a bool into a brush color.
/// True returns the "on" color (e.g., red for active state), False returns the "off" color (e.g., white for inactive state).
/// </summary>
internal sealed partial class BoolToBrushConverter : IValueConverter
{
private static readonly SolidColorBrush OnBrush = new(Colors.Red);
private static readonly SolidColorBrush OffBrush = new(Colors.White);

public object Convert(object value, Type targetType, object parameter, string language)
=> value is not bool b
? throw new InvalidOperationException($"{nameof(BoolToBrushConverter)} can only be used with bool")
: b ? OnBrush : OffBrush;

public object ConvertBack(object value, Type targetType, object parameter, string language)
=> throw new NotSupportedException();
}
5 changes: 5 additions & 0 deletions src/JellyBox/Glyphs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,18 @@ internal static class Glyphs
// Playback
public const string Play = "\uE768";
public const string Pause = "\uE769";
public const string Movies = "\uE8B2";

// Volume
public const string VolumeMute = "\uE74F";
public const string VolumeLow = "\uE993";
public const string VolumeMedium = "\uE994";
public const string VolumeHigh = "\uE767";

// Actions
public const string Accept = "\uE8FB";
public const string More = "\uE712";

// Favorites
public const string HeartOutline = "\uEB51";
public const string HeartFilled = "\uEB52";
Expand Down
3 changes: 3 additions & 0 deletions src/JellyBox/Resources/Styles.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Converters="using:JellyBox.Converters">

<Converters:BoolToBrushConverter x:Key="BoolToBrushConverter" />
<Converters:EmptyCollectionToVisibilityConverter x:Key="EmptyCollectionToVisibilityConverter" />
<Converters:NegateConverter x:Key="NegateConverter" />
<Converters:VisibleIfNotNullConverter x:Key="VisibleIfNotNullConverter" />

<FontFamily x:Key="SegoeIcons">Segoe MDL2 Assets</FontFamily>

<SolidColorBrush x:Key="Color0" Color="#101010" />
<SolidColorBrush x:Key="Color10" Color="#202020" />
<SolidColorBrush x:Key="Color20" Color="#303030" />
Expand Down
14 changes: 0 additions & 14 deletions src/JellyBox/ViewModels/ItemDetailsViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
using JellyBox.Views;
using Jellyfin.Sdk;
using Jellyfin.Sdk.Generated.Models;
using Windows.UI;
using Windows.UI.Xaml.Media;

namespace JellyBox.ViewModels;

Expand All @@ -25,9 +23,6 @@ internal sealed record MediaSourceInfoWrapper(string DisplayText, MediaSourceInf
internal sealed partial class ItemDetailsViewModel : ObservableObject
#pragma warning restore CA1812 // Avoid uninstantiated internal classes
{
private static readonly SolidColorBrush OnBrush = new SolidColorBrush(Colors.Red);
private static readonly SolidColorBrush OffBrush = new SolidColorBrush(Colors.White);

private readonly JellyfinApiClient _jellyfinApiClient;
private readonly JellyfinImageResolver _imageResolver;
private readonly NavigationManager _navigationManager;
Expand Down Expand Up @@ -87,15 +82,9 @@ internal sealed partial class ItemDetailsViewModel : ObservableObject
[ObservableProperty]
public partial bool IsPlayed { get; set; }

[ObservableProperty]
public partial Brush? PlayStateBrush { get; set; }

[ObservableProperty]
public partial bool IsFavorite { get; set; }

[ObservableProperty]
public partial Brush? FavoriteBrush { get; set; }

[ObservableProperty]
public partial List<Section>? Sections { get; set; }

Expand Down Expand Up @@ -460,10 +449,7 @@ private void UpdateUserData()
}

IsPlayed = Item.UserData!.Played.GetValueOrDefault();
PlayStateBrush = IsPlayed ? OnBrush : OffBrush;

IsFavorite = Item.UserData.IsFavorite.GetValueOrDefault();
FavoriteBrush = IsFavorite ? OnBrush : OffBrush;
}

private async Task<Section?> GetNextUpSectionAsync()
Expand Down
21 changes: 12 additions & 9 deletions src/JellyBox/Views/ItemDetails.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
xmlns:Behaviors="using:JellyBox.Behaviors"
xmlns:uc="using:JellyBox.Controls"
xmlns:m="using:JellyBox.Models"
xmlns:g="using:JellyBox"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Expand Down Expand Up @@ -110,34 +111,36 @@
<Interactivity:Interaction.Behaviors>
<Behaviors:FocusOnLoadBehavior />
</Interactivity:Interaction.Behaviors>
<SymbolIcon Symbol="Play" />
<FontIcon Glyph="{x:Bind g:Glyphs.Play}" FontFamily="{StaticResource SegoeIcons}" />
</Button>
<Button
Margin="0 8 0 8"
Click="{x:Bind ViewModel.PlayTrailer}"
Visibility="{x:Bind ViewModel.HasTrailer, Mode=OneWay}">
<SymbolIcon Symbol="SlideShow" />
<FontIcon Glyph="{x:Bind g:Glyphs.Movies}" FontFamily="{StaticResource SegoeIcons}" />
</Button>
<Button
Margin="0 8 0 8"
Click="{x:Bind ViewModel.TogglePlayed}"
Visibility="{x:Bind ViewModel.CanMarkPlayed, Mode=OneWay}">
<SymbolIcon
Symbol="Accept"
Foreground="{x:Bind ViewModel.PlayStateBrush, Mode=OneWay}" />
<FontIcon
Glyph="{x:Bind g:Glyphs.Accept}"
FontFamily="{StaticResource SegoeIcons}"
Foreground="{x:Bind ViewModel.IsPlayed, Mode=OneWay, Converter={StaticResource BoolToBrushConverter}}" />
</Button>
<Button
Margin="0 8 0 8"
Click="{x:Bind ViewModel.ToggleFavorite}"
Visibility="{x:Bind ViewModel.CanMarkFavorite, Mode=OneWay}">
<SymbolIcon
Symbol="Favorite"
Foreground="{x:Bind ViewModel.FavoriteBrush, Mode=OneWay}" />
<FontIcon
Glyph="{x:Bind g:Glyphs.HeartFilled}"
FontFamily="{StaticResource SegoeIcons}"
Foreground="{x:Bind ViewModel.IsFavorite, Mode=OneWay, Converter={StaticResource BoolToBrushConverter}}" />
</Button>
<!-- TODO: More commands -->
<Button
Margin="0 8 0 8">
<SymbolIcon Symbol="More" />
<FontIcon Glyph="{x:Bind g:Glyphs.More}" FontFamily="{StaticResource SegoeIcons}" />
</Button>
</StackPanel>
</Grid>
Expand Down