Skip to content

Commit 142d087

Browse files
committed
feat: Enhance artist lookup functionality with candidate selection and merging capabilities
1 parent 11b3e36 commit 142d087

11 files changed

Lines changed: 106 additions & 5 deletions

src/Melodee.Blazor/Components/Dialogs/ArtistLookupDialog.razor

Lines changed: 76 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,17 @@
8484
}
8585
else if (_candidates != null && _candidates.Length > 0)
8686
{
87+
<RadzenText Text="@L("ArtistLookup.SelectToMerge")" class="rz-text-secondary rz-mb-2" TextStyle="TextStyle.Caption"/>
8788
<RadzenStack Gap="0.5rem" class="rz-mt-2" Style="max-height: 400px; overflow-y: auto;">
8889
@foreach (var candidate in _candidates)
8990
{
90-
<RadzenCard class="candidate-card" Click="@(() => SelectCandidate(candidate))">
91+
<RadzenCard class="@GetCandidateCardClass(candidate)" Click="@(() => ToggleCandidateSelection(candidate))">
9192
<RadzenStack Gap="0.5rem">
9293
<RadzenStack Orientation="Orientation.Horizontal" Gap="0.5rem" AlignItems="AlignItems.Center">
94+
<RadzenCheckBox TValue="bool"
95+
Value="@_selectedCandidates.Contains(candidate)"
96+
Change="@((bool _) => ToggleCandidateSelection(candidate))"
97+
class="rz-mr-2"/>
9398
@if (!string.IsNullOrEmpty(candidate.ThumbnailUrl))
9499
{
95100
<RadzenImage Path="@candidate.ThumbnailUrl"
@@ -112,7 +117,7 @@
112117
</RadzenStack>
113118
</RadzenStack>
114119

115-
<RadzenStack Orientation="Orientation.Horizontal" Gap="0.25rem" class="rz-mt-1">
120+
<RadzenStack Orientation="Orientation.Horizontal" Gap="0.25rem" class="rz-mt-1" Wrap="FlexWrap.Wrap">
116121
@if (candidate.MusicBrainzId.HasValue)
117122
{
118123
<RadzenBadge BadgeStyle="BadgeStyle.Info" Text="@($"MB: {candidate.MusicBrainzId.Value.ToString()[..8]}...")"/>
@@ -133,6 +138,14 @@
133138
{
134139
<RadzenBadge BadgeStyle="BadgeStyle.Secondary" Text="@($"iTunes: {candidate.ItunesId}")"/>
135140
}
141+
@if (!string.IsNullOrEmpty(candidate.WikiDataId))
142+
{
143+
<RadzenBadge BadgeStyle="BadgeStyle.Light" Text="@($"WikiData: {candidate.WikiDataId}")"/>
144+
}
145+
@if (!string.IsNullOrEmpty(candidate.LastFmId))
146+
{
147+
<RadzenBadge BadgeStyle="BadgeStyle.Dark" Text="@($"Last.fm: {candidate.LastFmId}")"/>
148+
}
136149
</RadzenStack>
137150
</RadzenStack>
138151
</RadzenCard>
@@ -155,6 +168,13 @@
155168
<RadzenButton Text="@L("Actions.Cancel")"
156169
ButtonStyle="ButtonStyle.Light"
157170
Click="@(() => DialogService.Close(null))"/>
171+
@if (_selectedCandidates.Count > 0)
172+
{
173+
<RadzenButton Text="@L("Actions.Save")"
174+
Icon="save"
175+
ButtonStyle="ButtonStyle.Primary"
176+
Click="@SaveSelectedCandidates"/>
177+
}
158178
</RadzenStack>
159179
</RadzenStack>
160180

@@ -170,6 +190,7 @@
170190
private bool _hasPartialFailures;
171191
private CancellationTokenSource? _searchCts;
172192
private IArtistSearchEnginePlugin[] _plugins = [];
193+
private readonly HashSet<ArtistLookupCandidate> _selectedCandidates = new();
173194

174195
[Parameter]
175196
public string? InitialArtistName { get; set; }
@@ -226,6 +247,7 @@
226247

227248
_searchCts?.Cancel();
228249
_searchCts = new CancellationTokenSource();
250+
_selectedCandidates.Clear();
229251

230252
_isLoading = true;
231253
_hasError = false;
@@ -284,6 +306,7 @@
284306

285307
_searchCts?.Cancel();
286308
_searchCts = new CancellationTokenSource();
309+
_selectedCandidates.Clear();
287310

288311
_isLoading = true;
289312
_hasError = false;
@@ -330,19 +353,67 @@
330353
}
331354
}
332355

333-
private void SelectCandidate(ArtistLookupCandidate candidate)
356+
private void ToggleCandidateSelection(ArtistLookupCandidate candidate)
357+
{
358+
if (!_selectedCandidates.Remove(candidate))
359+
{
360+
_selectedCandidates.Add(candidate);
361+
}
362+
}
363+
364+
private string GetCandidateCardClass(ArtistLookupCandidate candidate)
365+
{
366+
return _selectedCandidates.Contains(candidate)
367+
? "candidate-card candidate-card-selected"
368+
: "candidate-card";
369+
}
370+
371+
private void SaveSelectedCandidates()
334372
{
335-
DialogService.Close(candidate);
373+
if (_selectedCandidates.Count == 0)
374+
{
375+
return;
376+
}
377+
378+
// Merge all selected candidates into a single result with combined provider IDs
379+
var merged = new ArtistLookupCandidate
380+
{
381+
ProviderDisplayName = string.Join(", ", _selectedCandidates.Select(c => c.ProviderDisplayName).Distinct()),
382+
ProviderId = _selectedCandidates.FirstOrDefault(c => c.ProviderId != null)?.ProviderId,
383+
Name = _selectedCandidates.First().Name,
384+
SortName = _selectedCandidates.FirstOrDefault(c => c.SortName != null)?.SortName,
385+
ImageUrl = _selectedCandidates.FirstOrDefault(c => c.ImageUrl != null)?.ImageUrl,
386+
ThumbnailUrl = _selectedCandidates.FirstOrDefault(c => c.ThumbnailUrl != null)?.ThumbnailUrl,
387+
MusicBrainzId = _selectedCandidates.FirstOrDefault(c => c.MusicBrainzId.HasValue)?.MusicBrainzId,
388+
SpotifyId = _selectedCandidates.FirstOrDefault(c => !string.IsNullOrEmpty(c.SpotifyId))?.SpotifyId,
389+
DiscogsId = _selectedCandidates.FirstOrDefault(c => !string.IsNullOrEmpty(c.DiscogsId))?.DiscogsId,
390+
AmgId = _selectedCandidates.FirstOrDefault(c => !string.IsNullOrEmpty(c.AmgId))?.AmgId,
391+
WikiDataId = _selectedCandidates.FirstOrDefault(c => !string.IsNullOrEmpty(c.WikiDataId))?.WikiDataId,
392+
ItunesId = _selectedCandidates.FirstOrDefault(c => !string.IsNullOrEmpty(c.ItunesId))?.ItunesId,
393+
LastFmId = _selectedCandidates.FirstOrDefault(c => !string.IsNullOrEmpty(c.LastFmId))?.LastFmId
394+
};
395+
396+
DialogService.Close(merged);
336397
}
337398
}
338399

339400
<style>
340401
.candidate-card {
341402
cursor: pointer;
342-
transition: background-color 0.2s;
403+
transition: background-color 0.2s, border-color 0.2s;
404+
border: 2px solid transparent;
343405
}
344406
345407
.candidate-card:hover {
346408
background-color: var(--rz-base-200);
347409
}
410+
411+
.candidate-card-selected {
412+
border-color: var(--rz-primary);
413+
background-color: var(--rz-primary-lighter);
414+
}
415+
416+
.candidate-card-selected:hover {
417+
background-color: var(--rz-primary-light);
418+
}
348419
</style>

src/Melodee.Blazor/Resources/SharedResources.ar-SA.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4711,4 +4711,7 @@
47114711
<data name="Common.Albums" xml:space="preserve">
47124712
<value>[NEEDS TRANSLATION] Albums</value>
47134713
</data>
4714+
<data name="ArtistLookup.SelectToMerge" xml:space="preserve">
4715+
<value>[NEEDS TRANSLATION] Select one or more results to merge their provider IDs</value>
4716+
</data>
47144717
</root>

src/Melodee.Blazor/Resources/SharedResources.de-DE.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4845,4 +4845,7 @@
48454845
<data name="Common.Albums" xml:space="preserve">
48464846
<value>[NEEDS TRANSLATION] Albums</value>
48474847
</data>
4848+
<data name="ArtistLookup.SelectToMerge" xml:space="preserve">
4849+
<value>[NEEDS TRANSLATION] Select one or more results to merge their provider IDs</value>
4850+
</data>
48484851
</root>

src/Melodee.Blazor/Resources/SharedResources.es-ES.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4711,4 +4711,7 @@
47114711
<data name="Common.Albums" xml:space="preserve">
47124712
<value>[NEEDS TRANSLATION] Albums</value>
47134713
</data>
4714+
<data name="ArtistLookup.SelectToMerge" xml:space="preserve">
4715+
<value>[NEEDS TRANSLATION] Select one or more results to merge their provider IDs</value>
4716+
</data>
47144717
</root>

src/Melodee.Blazor/Resources/SharedResources.fr-FR.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4711,4 +4711,7 @@
47114711
<data name="Common.Albums" xml:space="preserve">
47124712
<value>[NEEDS TRANSLATION] Albums</value>
47134713
</data>
4714+
<data name="ArtistLookup.SelectToMerge" xml:space="preserve">
4715+
<value>[NEEDS TRANSLATION] Select one or more results to merge their provider IDs</value>
4716+
</data>
47144717
</root>

src/Melodee.Blazor/Resources/SharedResources.it-IT.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4845,4 +4845,7 @@
48454845
<data name="Common.Albums" xml:space="preserve">
48464846
<value>[NEEDS TRANSLATION] Albums</value>
48474847
</data>
4848+
<data name="ArtistLookup.SelectToMerge" xml:space="preserve">
4849+
<value>[NEEDS TRANSLATION] Select one or more results to merge their provider IDs</value>
4850+
</data>
48484851
</root>

src/Melodee.Blazor/Resources/SharedResources.ja-JP.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4845,4 +4845,7 @@
48454845
<data name="Common.Albums" xml:space="preserve">
48464846
<value>[NEEDS TRANSLATION] Albums</value>
48474847
</data>
4848+
<data name="ArtistLookup.SelectToMerge" xml:space="preserve">
4849+
<value>[NEEDS TRANSLATION] Select one or more results to merge their provider IDs</value>
4850+
</data>
48484851
</root>

src/Melodee.Blazor/Resources/SharedResources.pt-BR.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4845,4 +4845,7 @@
48454845
<data name="Common.Albums" xml:space="preserve">
48464846
<value>[NEEDS TRANSLATION] Albums</value>
48474847
</data>
4848+
<data name="ArtistLookup.SelectToMerge" xml:space="preserve">
4849+
<value>[NEEDS TRANSLATION] Select one or more results to merge their provider IDs</value>
4850+
</data>
48484851
</root>

src/Melodee.Blazor/Resources/SharedResources.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4893,4 +4893,7 @@
48934893
<data name="ArtistLookup.AmghelpText" xml:space="preserve">
48944894
<value>Enter an AMG Artist ID (digits only) to look up the artist</value>
48954895
</data>
4896+
<data name="ArtistLookup.SelectToMerge" xml:space="preserve">
4897+
<value>Select one or more results to merge their provider IDs</value>
4898+
</data>
48964899
</root>

src/Melodee.Blazor/Resources/SharedResources.ru-RU.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4711,4 +4711,7 @@
47114711
<data name="Common.Albums" xml:space="preserve">
47124712
<value>[NEEDS TRANSLATION] Albums</value>
47134713
</data>
4714+
<data name="ArtistLookup.SelectToMerge" xml:space="preserve">
4715+
<value>[NEEDS TRANSLATION] Select one or more results to merge their provider IDs</value>
4716+
</data>
47144717
</root>

0 commit comments

Comments
 (0)