diff --git a/src/JellyBox/Behaviors/ListViewBaseCommandBehavior.cs b/src/JellyBox/Behaviors/ListViewBaseCommandBehavior.cs
index 6936ef3..efa6568 100644
--- a/src/JellyBox/Behaviors/ListViewBaseCommandBehavior.cs
+++ b/src/JellyBox/Behaviors/ListViewBaseCommandBehavior.cs
@@ -1,27 +1,14 @@
-using System.Windows.Input;
+using JellyBox.Models;
using Microsoft.Xaml.Interactivity;
-using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace JellyBox.Behaviors;
///
-/// Creates an attached property for all ListViewBase controls allowing binding a command object to it's ItemClick event.
+/// Invokes the NavigateCommand on INavigable items when they are clicked in a ListViewBase control.
///
internal sealed class ListViewBaseCommandBehavior : Behavior
{
- public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(
- "Command",
- typeof(ICommand),
- typeof(ListViewBaseCommandBehavior),
- new PropertyMetadata(null));
-
- public ICommand Command
- {
- get => (ICommand)GetValue(CommandProperty);
- set => SetValue(CommandProperty, value);
- }
-
protected override void OnAttached()
{
base.OnAttached();
@@ -36,12 +23,14 @@ protected override void OnDetaching()
AssociatedObject.ItemClick -= ItemClicked;
}
- private void ItemClicked(object sender, ItemClickEventArgs e)
+ private static void ItemClicked(object sender, ItemClickEventArgs e)
{
- ICommand command = Command;
- if (command is not null && command.CanExecute(e.ClickedItem))
+ if (e.ClickedItem is INavigable navigable)
{
- command.Execute(e.ClickedItem);
+ if (navigable.NavigateCommand.CanExecute(null))
+ {
+ navigable.NavigateCommand.Execute(null);
+ }
}
}
}
\ No newline at end of file
diff --git a/src/JellyBox/Models/Card.cs b/src/JellyBox/Models/Card.cs
index 0d6d9fe..71c596a 100644
--- a/src/JellyBox/Models/Card.cs
+++ b/src/JellyBox/Models/Card.cs
@@ -1,5 +1,5 @@
+using System.Windows.Input;
using JellyBox.Services;
-using Jellyfin.Sdk.Generated.Models;
namespace JellyBox.Models;
@@ -11,10 +11,8 @@ internal enum CardShape
Banner,
}
-internal sealed record Card
+internal sealed record Card : INavigable
{
- public required BaseItemDto Item { get; init; }
-
public required string Name { get; init; }
public required int ImageWidth { get; init; }
@@ -22,4 +20,6 @@ internal sealed record Card
public required int ImageHeight { get; init; }
public required JellyfinImage Image { get; init; }
+
+ public required ICommand NavigateCommand { get; init; }
}
diff --git a/src/JellyBox/Models/CardFactory.cs b/src/JellyBox/Models/CardFactory.cs
index 994eb10..742ef78 100644
--- a/src/JellyBox/Models/CardFactory.cs
+++ b/src/JellyBox/Models/CardFactory.cs
@@ -1,3 +1,4 @@
+using CommunityToolkit.Mvvm.Input;
using JellyBox.Services;
using Jellyfin.Sdk.Generated.Models;
@@ -9,7 +10,8 @@ public static Card CreateFromItem(
BaseItemDto item,
CardShape shape,
ImageType? preferredImageType,
- JellyfinImageResolver imageResolver)
+ JellyfinImageResolver imageResolver,
+ NavigationManager navigationManager)
{
double aspectRatio = GetAspectRatio(shape);
ImageType imageType;
@@ -50,11 +52,11 @@ public static Card CreateFromItem(
return new Card
{
- Item = item,
Name = item.Name!,
ImageWidth = imageWidth,
ImageHeight = imageHeight,
Image = image,
+ NavigateCommand = new RelayCommand(() => navigationManager.NavigateToItem(item)),
};
}
diff --git a/src/JellyBox/Models/INavigable.cs b/src/JellyBox/Models/INavigable.cs
new file mode 100644
index 0000000..167adec
--- /dev/null
+++ b/src/JellyBox/Models/INavigable.cs
@@ -0,0 +1,11 @@
+using System.Windows.Input;
+
+namespace JellyBox.Models;
+
+///
+/// Interface for UI models that support navigation when activated.
+///
+internal interface INavigable
+{
+ ICommand NavigateCommand { get; }
+}
diff --git a/src/JellyBox/Models/Section.cs b/src/JellyBox/Models/Section.cs
index 311cc7e..bea505b 100644
--- a/src/JellyBox/Models/Section.cs
+++ b/src/JellyBox/Models/Section.cs
@@ -1,5 +1,3 @@
-using System.Windows.Input;
-
namespace JellyBox.Models;
internal sealed class Section
@@ -7,6 +5,4 @@ internal sealed class Section
public required string Name { get; set; }
public required IReadOnlyList? Cards { get; set; }
-
- public required ICommand NavigateToCardCommand { get; set; }
}
\ No newline at end of file
diff --git a/src/JellyBox/Resources/Templates.xaml b/src/JellyBox/Resources/Templates.xaml
index a2bdda9..5496d5e 100644
--- a/src/JellyBox/Resources/Templates.xaml
+++ b/src/JellyBox/Resources/Templates.xaml
@@ -25,7 +25,7 @@
ScrollViewer.VerticalScrollMode="Disabled"
SelectionMode="None">
-
+
diff --git a/src/JellyBox/ViewModels/HomeViewModel.cs b/src/JellyBox/ViewModels/HomeViewModel.cs
index 24ae53f..7aa8bfd 100644
--- a/src/JellyBox/ViewModels/HomeViewModel.cs
+++ b/src/JellyBox/ViewModels/HomeViewModel.cs
@@ -1,6 +1,5 @@
using System.Collections.ObjectModel;
using CommunityToolkit.Mvvm.ComponentModel;
-using CommunityToolkit.Mvvm.Input;
using JellyBox.Models;
using JellyBox.Services;
using Jellyfin.Sdk;
@@ -104,20 +103,13 @@ public async void Initialize()
continue;
}
- cards.Add(CardFactory.CreateFromItem(item, cardShape, preferredImageType, _imageResolver));
+ cards.Add(CardFactory.CreateFromItem(item, cardShape, preferredImageType, _imageResolver, _navigationManager));
}
return new Section
{
Name = name,
Cards = cards,
- NavigateToCardCommand = NavigateToCardCommand,
};
}
-
- [RelayCommand]
- private void NavigateToCard(Card card)
- {
- _navigationManager.NavigateToItem(card.Item);
- }
}
\ No newline at end of file
diff --git a/src/JellyBox/ViewModels/ItemDetailsViewModel.cs b/src/JellyBox/ViewModels/ItemDetailsViewModel.cs
index 7980cff..dc550ee 100644
--- a/src/JellyBox/ViewModels/ItemDetailsViewModel.cs
+++ b/src/JellyBox/ViewModels/ItemDetailsViewModel.cs
@@ -2,7 +2,6 @@
using System.Text;
using System.Text.RegularExpressions;
using CommunityToolkit.Mvvm.ComponentModel;
-using CommunityToolkit.Mvvm.Input;
using JellyBox.Models;
using JellyBox.Services;
using JellyBox.Views;
@@ -469,14 +468,13 @@ private void UpdateUserData()
continue;
}
- cards.Add(CardFactory.CreateFromItem(item, CardShape.Backdrop, ImageType.Thumb, _imageResolver));
+ cards.Add(CardFactory.CreateFromItem(item, CardShape.Backdrop, ImageType.Thumb, _imageResolver, _navigationManager));
}
return new Section
{
Name = "Next Up",
Cards = cards,
- NavigateToCardCommand = NavigateToCardCommand,
};
}
@@ -562,7 +560,7 @@ private void UpdateUserData()
continue;
}
- cards.Add(CardFactory.CreateFromItem(item, cardShape, ImageType.Thumb, _imageResolver));
+ cards.Add(CardFactory.CreateFromItem(item, cardShape, ImageType.Thumb, _imageResolver, _navigationManager));
}
// TODO: Support list view for Type == MusicAlbum | Season
@@ -570,16 +568,9 @@ private void UpdateUserData()
{
Name = sectionName,
Cards = cards,
- NavigateToCardCommand = NavigateToCardCommand,
};
}
- [RelayCommand]
- private void NavigateToCard(Card card)
- {
- _navigationManager.NavigateToItem(card.Item);
- }
-
private static Uri GetWebVideoUri(string url)
{
Match match = YouTubeRegex.Match(url);
diff --git a/src/JellyBox/ViewModels/MoviesViewModel.cs b/src/JellyBox/ViewModels/MoviesViewModel.cs
index 7e694ce..b72cfb5 100644
--- a/src/JellyBox/ViewModels/MoviesViewModel.cs
+++ b/src/JellyBox/ViewModels/MoviesViewModel.cs
@@ -1,6 +1,5 @@
using System.Collections.ObjectModel;
using CommunityToolkit.Mvvm.ComponentModel;
-using CommunityToolkit.Mvvm.Input;
using JellyBox.Models;
using JellyBox.Services;
using JellyBox.Views;
@@ -66,14 +65,8 @@ private async Task InitializeMoviesAsync()
continue;
}
- Movies.Add(CardFactory.CreateFromItem(item, CardShape.Portrait, preferredImageType: null, _imageResolver));
+ Movies.Add(CardFactory.CreateFromItem(item, CardShape.Portrait, preferredImageType: null, _imageResolver, _navigationManager));
}
}
}
-
- [RelayCommand]
- private void NavigateToCard(Card card)
- {
- _navigationManager.NavigateToItem(card.Item);
- }
}
\ No newline at end of file
diff --git a/src/JellyBox/ViewModels/ShowsViewModel.cs b/src/JellyBox/ViewModels/ShowsViewModel.cs
index f0027e4..951d631 100644
--- a/src/JellyBox/ViewModels/ShowsViewModel.cs
+++ b/src/JellyBox/ViewModels/ShowsViewModel.cs
@@ -1,6 +1,5 @@
-using System.Collections.ObjectModel;
+using System.Collections.ObjectModel;
using CommunityToolkit.Mvvm.ComponentModel;
-using CommunityToolkit.Mvvm.Input;
using JellyBox.Models;
using JellyBox.Services;
using JellyBox.Views;
@@ -67,14 +66,8 @@ private async Task InitializeShowsAsync()
continue;
}
- Shows.Add(CardFactory.CreateFromItem(item, CardShape.Portrait, preferredImageType: null, _imageResolver));
+ Shows.Add(CardFactory.CreateFromItem(item, CardShape.Portrait, preferredImageType: null, _imageResolver, _navigationManager));
}
}
}
-
- [RelayCommand]
- private void NavigateToCard(Card card)
- {
- _navigationManager.NavigateToItem(card.Item);
- }
}
\ No newline at end of file
diff --git a/src/JellyBox/Views/ItemDetails.xaml b/src/JellyBox/Views/ItemDetails.xaml
index c6ce504..e55693f 100644
--- a/src/JellyBox/Views/ItemDetails.xaml
+++ b/src/JellyBox/Views/ItemDetails.xaml
@@ -253,7 +253,7 @@
ScrollViewer.VerticalScrollMode="Disabled"
SelectionMode="None">
-
+
diff --git a/src/JellyBox/Views/Movies.xaml b/src/JellyBox/Views/Movies.xaml
index 1525aec..9c43cd5 100644
--- a/src/JellyBox/Views/Movies.xaml
+++ b/src/JellyBox/Views/Movies.xaml
@@ -31,7 +31,7 @@
IsItemClickEnabled="True">
-
+
diff --git a/src/JellyBox/Views/Shows.xaml b/src/JellyBox/Views/Shows.xaml
index be511c3..40a779f 100644
--- a/src/JellyBox/Views/Shows.xaml
+++ b/src/JellyBox/Views/Shows.xaml
@@ -31,7 +31,7 @@
IsItemClickEnabled="True">
-
+