implemented search artists in MusicBrainz
This commit is contained in:
@@ -4,6 +4,11 @@ root = true
|
|||||||
# All files
|
# All files
|
||||||
[*]
|
[*]
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
|
indent_style = tab
|
||||||
|
indent_size = 4
|
||||||
|
tab_width = 4
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
# C# files
|
# C# files
|
||||||
[*.cs]
|
[*.cs]
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
<None Remove="Pages\FavoriteAlbums.xaml" />
|
<None Remove="Pages\FavoriteAlbums.xaml" />
|
||||||
<None Remove="Pages\FavoriteArtists.xaml" />
|
<None Remove="Pages\FavoriteArtists.xaml" />
|
||||||
<None Remove="Pages\FavoriteTracks.xaml" />
|
<None Remove="Pages\FavoriteTracks.xaml" />
|
||||||
|
<None Remove="Pages\Search.xaml" />
|
||||||
<None Remove="Pages\Settings.xaml" />
|
<None Remove="Pages\Settings.xaml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
@@ -89,4 +90,10 @@
|
|||||||
<None Include="D:\work\Harmony\HarmonyWinUI\.editorconfig" />
|
<None Include="D:\work\Harmony\HarmonyWinUI\.editorconfig" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Update="Pages\Search.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -17,6 +17,9 @@
|
|||||||
<None Update="Package.appxmanifest">
|
<None Update="Package.appxmanifest">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</None>
|
</None>
|
||||||
|
<Page Update="Pages\Search.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
<Page Update="Pages\Settings.xaml">
|
<Page Update="Pages\Settings.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Page>
|
</Page>
|
||||||
|
|||||||
@@ -30,8 +30,10 @@
|
|||||||
PaneDisplayMode="Left"
|
PaneDisplayMode="Left"
|
||||||
PaneTitle="Harmony"
|
PaneTitle="Harmony"
|
||||||
x:Name="MainNavigation"
|
x:Name="MainNavigation"
|
||||||
SelectionChanged="MainNavigation_SelectionChanged">
|
SelectionChanged="MainNavigation_SelectionChanged"
|
||||||
|
IsBackButtonVisible="Visible"
|
||||||
|
BackRequested="MainNavigation_BackRequested">
|
||||||
|
|
||||||
<NavigationView.MenuItems>
|
<NavigationView.MenuItems>
|
||||||
|
|
||||||
<NavigationViewItem Icon="Home" Content="Dashboard" Tag="Dashboard" />
|
<NavigationViewItem Icon="Home" Content="Dashboard" Tag="Dashboard" />
|
||||||
@@ -40,7 +42,7 @@
|
|||||||
<NavigationViewItem Icon="Contact" Content="Favorite artists" Tag="FavoriteArtists" />
|
<NavigationViewItem Icon="Contact" Content="Favorite artists" Tag="FavoriteArtists" />
|
||||||
|
|
||||||
</NavigationView.MenuItems>
|
</NavigationView.MenuItems>
|
||||||
|
|
||||||
<NavigationView.FooterMenuItems>
|
<NavigationView.FooterMenuItems>
|
||||||
<NavigationViewItem Content="Donate" Tag="PageDonate" >
|
<NavigationViewItem Content="Donate" Tag="PageDonate" >
|
||||||
<NavigationViewItem.Icon>
|
<NavigationViewItem.Icon>
|
||||||
@@ -50,7 +52,8 @@
|
|||||||
<NavigationViewItem Content="Homepage" Tag="PageHomepage" Icon="Globe" />
|
<NavigationViewItem Content="Homepage" Tag="PageHomepage" Icon="Globe" />
|
||||||
</NavigationView.FooterMenuItems>
|
</NavigationView.FooterMenuItems>
|
||||||
|
|
||||||
<Frame x:Name="MainNavigationContentFrame" />
|
<Frame x:Name="MainNavigationContentFrame"
|
||||||
|
Navigated="MainNavigationContentFrame_Navigated"/>
|
||||||
|
|
||||||
</NavigationView>
|
</NavigationView>
|
||||||
|
|
||||||
@@ -100,7 +103,7 @@
|
|||||||
RadiusY="6"
|
RadiusY="6"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
Fill="{ThemeResource SystemControlBackgroundBaseMediumBrush}"/>
|
Fill="{ThemeResource SystemControlBackgroundBaseMediumBrush}"/>
|
||||||
<TextBlock Grid.Column="1"
|
<TextBlock Grid.Column="1"
|
||||||
Text="{x:Bind TrackName}"
|
Text="{x:Bind TrackName}"
|
||||||
x:Phase="1"
|
x:Phase="1"
|
||||||
@@ -111,7 +114,7 @@
|
|||||||
Text="{x:Bind ArtistName}"
|
Text="{x:Bind ArtistName}"
|
||||||
x:Phase="2"
|
x:Phase="2"
|
||||||
Style="{ThemeResource BodyTextBlockStyle}"
|
Style="{ThemeResource BodyTextBlockStyle}"
|
||||||
Margin="12,0,0,6"/>
|
Margin="12,0,0,6"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ListView.ItemTemplate>
|
</ListView.ItemTemplate>
|
||||||
|
|||||||
@@ -69,6 +69,19 @@ namespace HarmonyWinUI
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void MainNavigation_BackRequested(NavigationView sender, NavigationViewBackRequestedEventArgs args)
|
||||||
|
{
|
||||||
|
if (MainNavigationContentFrame.CanGoBack)
|
||||||
|
{
|
||||||
|
MainNavigationContentFrame.GoBack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MainNavigationContentFrame_Navigated(object sender, Microsoft.UI.Xaml.Navigation.NavigationEventArgs e)
|
||||||
|
{
|
||||||
|
MainNavigation.IsBackEnabled = MainNavigationContentFrame.CanGoBack;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class PlayListItem
|
public class PlayListItem
|
||||||
|
|||||||
@@ -0,0 +1,96 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace HarmonyWinUI.Models
|
||||||
|
{
|
||||||
|
class MusicBrainz
|
||||||
|
{
|
||||||
|
private String URLprefix = "https://musicbrainz.org/ws/2/";
|
||||||
|
private static readonly HttpClient httpClient = createHttpClient();
|
||||||
|
|
||||||
|
public async Task<List<MusicBrainzArtist>> getArtists(String query)
|
||||||
|
{
|
||||||
|
ArgumentException.ThrowIfNullOrWhiteSpace(query);
|
||||||
|
|
||||||
|
string searchQuery = Uri.EscapeDataString($"artist:{query}");
|
||||||
|
MusicBrainzArtistResponse? response = await getData<MusicBrainzArtistResponse>(
|
||||||
|
$"artist?query={searchQuery}&fmt=json&limit=10"
|
||||||
|
);
|
||||||
|
|
||||||
|
return response?.Artists ?? new List<MusicBrainzArtist>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<T?> getData<T>(String relativeURL)
|
||||||
|
{
|
||||||
|
Uri requestURL = new Uri(new Uri(URLprefix), relativeURL);
|
||||||
|
|
||||||
|
using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, requestURL);
|
||||||
|
using HttpResponseMessage response = await httpClient.SendAsync(
|
||||||
|
request,
|
||||||
|
HttpCompletionOption.ResponseHeadersRead
|
||||||
|
);
|
||||||
|
response.EnsureSuccessStatusCode();
|
||||||
|
|
||||||
|
await using Stream jsonStream = await response.Content.ReadAsStreamAsync();
|
||||||
|
return await JsonSerializer.DeserializeAsync<T>(jsonStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static HttpClient createHttpClient()
|
||||||
|
{
|
||||||
|
HttpClient client = new HttpClient
|
||||||
|
{
|
||||||
|
Timeout = TimeSpan.FromSeconds(30)
|
||||||
|
};
|
||||||
|
client.DefaultRequestHeaders.UserAgent.ParseAdd(
|
||||||
|
"HarmonyWinUI/1.0 (https://harmony.tpsoft.org/)"
|
||||||
|
);
|
||||||
|
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class MusicBrainzArtistResponse
|
||||||
|
{
|
||||||
|
[JsonPropertyName("artists")]
|
||||||
|
public List<MusicBrainzArtist>? Artists { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MusicBrainzArtist
|
||||||
|
{
|
||||||
|
public string? ID { get; set; }
|
||||||
|
public string? Type { get; set; }
|
||||||
|
[JsonPropertyName("type-id")]
|
||||||
|
public string? TypeID { get; set; }
|
||||||
|
public int? Score { get; set; }
|
||||||
|
public string? Name { get; set; } = "";
|
||||||
|
public string? Gender { get; set; }
|
||||||
|
public string? Country { get; set; }
|
||||||
|
public string? ImageURL { get; set; }
|
||||||
|
|
||||||
|
public MusicBrainzArtist() { }
|
||||||
|
|
||||||
|
public MusicBrainzArtist(
|
||||||
|
string? id,
|
||||||
|
string? type,
|
||||||
|
string? typeID,
|
||||||
|
int? score,
|
||||||
|
string? name,
|
||||||
|
string? gender,
|
||||||
|
string? country)
|
||||||
|
{
|
||||||
|
this.ID = id;
|
||||||
|
this.Type = type;
|
||||||
|
this.TypeID = typeID;
|
||||||
|
this.Score = score;
|
||||||
|
this.Name = name;
|
||||||
|
this.Gender = gender;
|
||||||
|
this.Country = country;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace HarmonyWinUI.Models
|
||||||
|
{
|
||||||
|
class YTDLP
|
||||||
|
{
|
||||||
|
private String binPath = string.Empty;
|
||||||
|
|
||||||
|
public YTDLP()
|
||||||
|
{
|
||||||
|
this.binPath = this.findBinnary();
|
||||||
|
System.Diagnostics.Debug.WriteLine("binPath = " + this.binPath);
|
||||||
|
if (this.binPath.Equals(string.Empty))
|
||||||
|
{
|
||||||
|
throw new Exception("Binnary for YT-DLP not found.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String findBinnary()
|
||||||
|
{
|
||||||
|
DirectoryInfo? currentDirectory = new DirectoryInfo(AppContext.BaseDirectory);
|
||||||
|
|
||||||
|
while (currentDirectory != null)
|
||||||
|
{
|
||||||
|
string candidatePath = Path.Combine(
|
||||||
|
currentDirectory.FullName,
|
||||||
|
"vendor",
|
||||||
|
"yt-dlp.exe"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (File.Exists(candidatePath))
|
||||||
|
{
|
||||||
|
return candidatePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentDirectory = currentDirectory.Parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,14 +19,16 @@
|
|||||||
|
|
||||||
<!-- Search -->
|
<!-- Search -->
|
||||||
<TextBox
|
<TextBox
|
||||||
PlaceholderText="🔎 Search artists, albums and songs..."
|
x:Name="SearchBox"
|
||||||
HorizontalAlignment="Stretch" />
|
PlaceholderText="🔎 Search artists, albums and songs..."
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
KeyDown="SearchBox_KeyDown"/>
|
||||||
|
|
||||||
<!-- Last Artists -->
|
<!-- Last Artists -->
|
||||||
<StackPanel Spacing="12">
|
<StackPanel Spacing="12">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="Last artists"
|
Text="Last artists"
|
||||||
Style="{StaticResource TitleTextBlockStyle}" />
|
Style="{StaticResource TitleTextBlockStyle}" />
|
||||||
|
|
||||||
<ListView>
|
<ListView>
|
||||||
<!-- Artists -->
|
<!-- Artists -->
|
||||||
@@ -36,30 +38,30 @@
|
|||||||
<!-- Last Albums -->
|
<!-- Last Albums -->
|
||||||
<StackPanel Spacing="12">
|
<StackPanel Spacing="12">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="Last albums"
|
Text="Last albums"
|
||||||
Style="{StaticResource TitleTextBlockStyle}" />
|
Style="{StaticResource TitleTextBlockStyle}" />
|
||||||
|
|
||||||
<ListView>
|
<ListView>
|
||||||
<!-- Albums -->
|
<!-- Albums -->
|
||||||
</ListView>
|
</ListView>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<!-- Last Songs -->
|
<!-- Last Tracks -->
|
||||||
<StackPanel Spacing="12">
|
<StackPanel Spacing="12">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="Last songs"
|
Text="Last tracks"
|
||||||
Style="{StaticResource TitleTextBlockStyle}" />
|
Style="{StaticResource TitleTextBlockStyle}" />
|
||||||
|
|
||||||
<ListView>
|
<ListView>
|
||||||
<!-- Songs -->
|
<!-- Tracks -->
|
||||||
</ListView>
|
</ListView>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<!-- New Releases -->
|
<!-- New Releases -->
|
||||||
<StackPanel Spacing="12">
|
<StackPanel Spacing="12">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="New releases"
|
Text="New releases"
|
||||||
Style="{StaticResource TitleTextBlockStyle}" />
|
Style="{StaticResource TitleTextBlockStyle}" />
|
||||||
|
|
||||||
<!-- Content loaded from internet -->
|
<!-- Content loaded from internet -->
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|||||||
@@ -1,17 +1,6 @@
|
|||||||
using Microsoft.UI.Xaml;
|
|
||||||
using Microsoft.UI.Xaml.Controls;
|
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.Input;
|
||||||
using Microsoft.UI.Xaml.Media;
|
using Windows.System;
|
||||||
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;
|
|
||||||
|
|
||||||
// To learn more about WinUI, the WinUI project structure,
|
// To learn more about WinUI, the WinUI project structure,
|
||||||
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
||||||
@@ -27,5 +16,22 @@ namespace HarmonyWinUI.Pages
|
|||||||
{
|
{
|
||||||
InitializeComponent();
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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="" />
|
||||||
|
</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>
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user