implemented search artists in MusicBrainz

This commit is contained in:
2026-08-17 01:10:30 +02:00
parent b02feb0b9f
commit 2d12ec2818
11 changed files with 419 additions and 30 deletions
+14 -12
View File
@@ -19,14 +19,16 @@
<!-- Search -->
<TextBox
PlaceholderText="🔎 Search artists, albums and songs..."
HorizontalAlignment="Stretch" />
x:Name="SearchBox"
PlaceholderText="🔎 Search artists, albums and songs..."
HorizontalAlignment="Stretch"
KeyDown="SearchBox_KeyDown"/>
<!-- Last Artists -->
<StackPanel Spacing="12">
<TextBlock
Text="Last artists"
Style="{StaticResource TitleTextBlockStyle}" />
Text="Last artists"
Style="{StaticResource TitleTextBlockStyle}" />
<ListView>
<!-- Artists -->
@@ -36,30 +38,30 @@
<!-- Last Albums -->
<StackPanel Spacing="12">
<TextBlock
Text="Last albums"
Style="{StaticResource TitleTextBlockStyle}" />
Text="Last albums"
Style="{StaticResource TitleTextBlockStyle}" />
<ListView>
<!-- Albums -->
</ListView>
</StackPanel>
<!-- Last Songs -->
<!-- Last Tracks -->
<StackPanel Spacing="12">
<TextBlock
Text="Last songs"
Style="{StaticResource TitleTextBlockStyle}" />
Text="Last tracks"
Style="{StaticResource TitleTextBlockStyle}" />
<ListView>
<!-- Songs -->
<!-- Tracks -->
</ListView>
</StackPanel>
<!-- New Releases -->
<StackPanel Spacing="12">
<TextBlock
Text="New releases"
Style="{StaticResource TitleTextBlockStyle}" />
Text="New releases"
Style="{StaticResource TitleTextBlockStyle}" />
<!-- Content loaded from internet -->
</StackPanel>
+18 -12
View File
@@ -1,17 +1,6 @@
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.System;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
@@ -27,5 +16,22 @@ namespace HarmonyWinUI.Pages
{
InitializeComponent();
}
private void SearchBox_KeyDown(object sender, KeyRoutedEventArgs e)
{
if (e.Key == VirtualKey.Enter)
{
string searchText = SearchBox.Text;
Search(searchText);
}
}
private void Search(string searchText)
{
// Implement your search logic here
// For example, you can navigate to a search results page or filter a list of items
System.Diagnostics.Debug.WriteLine($"Searching for: {searchText}");
Frame.Navigate(typeof(Search), searchText);
}
}
}
+97
View File
@@ -0,0 +1,97 @@
<?xml version="1.0" encoding="utf-8"?>
<Page
x:Class="HarmonyWinUI.Pages.Search"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:HarmonyWinUI.Pages"
xmlns:models="using:HarmonyWinUI.Models"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Resources>
<local:ImageUrlToImageSourceConverter x:Key="ImageUrlToImageSourceConverter" />
</Page.Resources>
<ScrollViewer>
<StackPanel
Padding="24"
Spacing="24">
<TextBlock Text="Search" FontFamily="Arial"
FontSize="24" TextWrapping="WrapWholeWords"
CharacterSpacing="200" Foreground="LightGray" />
<TextBlock x:Name="TextBlockQuery" Text="Query: " FontFamily="Arial"
FontSize="14" TextWrapping="WrapWholeWords"
CharacterSpacing="100" Foreground="LightGray" />
<!-- Artists -->
<StackPanel Spacing="12">
<TextBlock
Text="Artists"
Style="{StaticResource TitleTextBlockStyle}" />
<ListView
x:Name="ArtistsListView"
ItemsSource="{x:Bind Artists}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="models:MusicBrainzArtist">
<StackPanel
Orientation="Horizontal"
Spacing="12"
Padding="4">
<Grid
Width="48"
Height="48">
<Border
Background="{ThemeResource SystemControlBackgroundBaseMediumBrush}"
CornerRadius="24">
<FontIcon
FontSize="24"
Glyph="&#xE77B;" />
</Border>
<Image
Source="{Binding ImageURL, Converter={StaticResource ImageUrlToImageSourceConverter}}"
Stretch="UniformToFill" />
</Grid>
<TextBlock
Text="{x:Bind Name}"
VerticalAlignment="Center" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
<!-- Albums -->
<StackPanel Spacing="12">
<TextBlock
Text="Albums"
Style="{StaticResource TitleTextBlockStyle}" />
<ListView>
<!-- Albums -->
</ListView>
</StackPanel>
<!-- Tracks -->
<StackPanel Spacing="12">
<TextBlock
Text="Tracks"
Style="{StaticResource TitleTextBlockStyle}" />
<ListView>
<!-- Tracks -->
</ListView>
</StackPanel>
</StackPanel>
</ScrollViewer>
</Page>
+114
View File
@@ -0,0 +1,114 @@
using HarmonyWinUI.Models;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Media.Imaging;
using Microsoft.UI.Xaml.Navigation;
using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace HarmonyWinUI.Pages;
public sealed class ImageUrlToImageSourceConverter : IValueConverter
{
public object? Convert(object value, Type targetType, object parameter, string language)
{
if (value is string imageUrl
&& Uri.TryCreate(imageUrl, UriKind.Absolute, out Uri? imageUri))
{
return new BitmapImage(imageUri);
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotSupportedException();
}
}
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class Search : Page
{
public ObservableCollection<MusicBrainzArtist> Artists { get; } = new();
private string? pendingSearchText;
public Search()
{
InitializeComponent();
Loaded += Search_Loaded;
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
pendingSearchText = e.Parameter as string;
}
private async void Search_Loaded(object sender, RoutedEventArgs e)
{
if (pendingSearchText is not string searchText)
{
return;
}
pendingSearchText = null;
await SearchText(searchText);
}
private async Task SearchText(string searchText)
{
TextBlockQuery.Text = $"Query: '{searchText}'";
var mb = new MusicBrainz();
while (true)
{
try
{
var artists = await mb.getArtists(searchText);
this.Artists.Clear();
foreach (var artist in artists)
{
this.Artists.Add(artist);
}
return;
}
catch (Exception exception) when (
exception is HttpRequestException
or IOException
or JsonException
or TaskCanceledException
)
{
ContentDialog errorDialog = new ContentDialog
{
XamlRoot = XamlRoot,
Title = "MusicBrainz connection failed",
Content = $"{exception.GetType().Name}: {exception.Message}",
PrimaryButtonText = "Retry",
CloseButtonText = "Cancel",
DefaultButton = ContentDialogButton.Primary
};
ContentDialogResult result = await errorDialog.ShowAsync();
if (result != ContentDialogResult.Primary)
{
this.Artists.Clear();
return;
}
}
}
}
}