Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(#604) Fix packaged application creation #605

Merged
merged 1 commit into from
Jan 4, 2025
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
23 changes: 23 additions & 0 deletions src/Infra/Lanceur.Infra.Win32/Services/PackagedAppSearchService.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using System.IO;
using Lanceur.Core.Models;
using Lanceur.Core.Services;
using Lanceur.Infra.Logging;
using Lanceur.Infra.Win32.PackagedApp;
using Lanceur.SharedKernel.Mixins;
using Microsoft.Extensions.Logging;

namespace Lanceur.Infra.Win32.Services;
Expand All @@ -22,6 +24,7 @@ public class PackagedAppSearchService : AbstractPackagedAppSearchService, IPacka

#region Methods

/// <inheritdoc />
public async Task<IEnumerable<Core.Models.PackagedApp>> GetByInstalledDirectory(string fileName)
{
fileName = fileName.Replace("package:", "");
Expand Down Expand Up @@ -59,5 +62,25 @@ public class PackagedAppSearchService : AbstractPackagedAppSearchService, IPacka
);
}

/// <inheritdoc />
public async Task<bool> TryResolveDetails(AliasQueryResult queryResult)
{
ArgumentNullException.ThrowIfNull(queryResult);
var results = await GetByInstalledDirectory(queryResult.FileName);
results = results.ToArray();

if (!results.Any()) return false;

var result = results.First();
if (queryResult.Notes.IsNullOrEmpty())
{
queryResult.Description = result.Description.IsNullOrEmpty()
? result.DisplayName
: result.Description;
}
queryResult.FileName = result.FileName;
return true;
}

#endregion
}
7 changes: 6 additions & 1 deletion src/Lanceur.Core/Models/AliasQueryResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,12 @@ public ObservableCollection<AdditionalParameter> AdditionalParameters
public override string Description
{
get => Notes.IsNullOrWhiteSpace() ? FileName : Notes;
set => Notes = value;
set
{
Notes = value;
OnPropertyChanged();
OnPropertyChanged(nameof(Notes));
}
}

public string FileName
Expand Down
5 changes: 3 additions & 2 deletions src/Lanceur.Core/Models/PackagedApp.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
namespace Lanceur.Core.Models;

public class PackagedApp
public record PackagedApp
{
#region Properties

public string AppUserModelId { get; init; }
public string Description { get; init; }
public string DisplayName { get; init; }
public string FileName => $"package:{AppUserModelId}";
public string InstalledLocation { get; init; }
public Uri Logo { get; init; }

#endregion Properties
#endregion
}
30 changes: 30 additions & 0 deletions src/Lanceur.Core/Services/IPackagedAppSearchService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,37 @@ public interface IPackagedAppSearchService
{
#region Methods

/// <summary>
/// Retrieves a collection of packaged applications that match the specified
/// installed directory or application user model ID.
/// </summary>
/// <param name="fileName">
/// The file name to search for, with a "package:" prefix that will be removed
/// during processing. Used to determine the installed directory and app user model ID.
/// </param>
/// <returns>
/// A task representing the asynchronous operation. The task result contains
/// an enumerable collection of packaged applications matching the specified criteria.
/// </returns>
Task<IEnumerable<PackagedApp>> GetByInstalledDirectory(string fileName);

/// <summary>
/// Attempts to populate the specified <see cref="AliasQueryResult"/> with details
/// of a packaged application that matches the provided file name.
/// </summary>
/// <param name="queryResult">
/// The query result object to populate with application details if a match is found.
/// Must not be null.
/// </param>
/// <returns>
/// A task representing the asynchronous operation. The task result is <c>true</c> if
/// the query result was successfully populated with packaged application details;
/// otherwise, <c>false</c>.
/// </returns>
/// <exception cref="ArgumentNullException">
/// Thrown if <paramref name="queryResult"/> is null.
/// </exception>
Task<bool> TryResolveDetails(AliasQueryResult queryResult);

#endregion Methods
}
10 changes: 9 additions & 1 deletion src/UI/Lanceur.Ui.Core/ViewModels/Pages/KeywordsViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public partial class KeywordsViewModel : ObservableObject
private readonly IUserNotificationService _userNotificationService;
private readonly IAliasValidationService _validationService;
private readonly IViewFactory _viewFactory;
private readonly IPackagedAppSearchService _packagedAppSearchService;

#endregion

Expand All @@ -42,7 +43,8 @@ public KeywordsViewModel(
IUserNotificationService userNotificationService,
IAliasValidationService validationService,
IUserInteractionService userInteraction,
IViewFactory viewFactory
IViewFactory viewFactory,
IPackagedAppSearchService packagedAppSearchService
)
{
ArgumentNullException.ThrowIfNull(aliasManagementService);
Expand All @@ -52,13 +54,15 @@ IViewFactory viewFactory
ArgumentNullException.ThrowIfNull(validationService);
ArgumentNullException.ThrowIfNull(userInteraction);
ArgumentNullException.ThrowIfNull(viewFactory);
ArgumentNullException.ThrowIfNull(packagedAppSearchService);

WeakReferenceMessenger.Default.Register<AddAliasMessage>(this, (r, m) => ((KeywordsViewModel)r).CreateAlias(m));

_userNotificationService = userNotificationService;
_validationService = validationService;
_userInteraction = userInteraction;
_viewFactory = viewFactory;
_packagedAppSearchService = packagedAppSearchService;
_aliasManagementService = aliasManagementService;
_thumbnailService = thumbnailService;
_logger = logger;
Expand Down Expand Up @@ -230,10 +234,14 @@ private async Task OnSaveCurrentAliasAsync()
{
_userNotificationService.Warn(result.ErrorContent, "Validation failed");
_logger.LogInformation("Validation failed for {AliasName}: {Errors}", SelectedAlias!.Name, result.ErrorContent);
_userNotificationService.Warn($"Alias validation failed:\n{result.ErrorContent}");
return;
}

_logger.LogTrace("Saving alias {AliasName}", SelectedAlias!.Name);

await _packagedAppSearchService.TryResolveDetails(SelectedAlias);

var alias = SelectedAlias;
await Task.Run(() => _aliasManagementService.SaveOrUpdate(ref alias));
_userNotificationService.Success($"Alias {alias.Name} created.", "Item created.");
Expand Down