DetailsViewModel.cs
 1  // Copyright (c) Microsoft Corporation
 2  // The Microsoft Corporation licenses this file to you under the MIT license.
 3  // See the LICENSE file in the project root for more information.
 4  
 5  using Microsoft.CmdPal.Core.ViewModels.Models;
 6  using Microsoft.CommandPalette.Extensions;
 7  
 8  namespace Microsoft.CmdPal.Core.ViewModels;
 9  
10  public partial class DetailsViewModel(IDetails _details, WeakReference<IPageContext> context) : ExtensionObjectViewModel(context)
11  {
12      private readonly ExtensionObject<IDetails> _detailsModel = new(_details);
13  
14      // Remember - "observable" properties from the model (via PropChanged)
15      // cannot be marked [ObservableProperty]
16      public IconInfoViewModel HeroImage { get; private set; } = new(null);
17  
18      public string Title { get; private set; } = string.Empty;
19  
20      public string Body { get; private set; } = string.Empty;
21  
22      public ContentSize? Size { get; private set; } = ContentSize.Small;
23  
24      // Metadata is an array of IDetailsElement,
25      //   where IDetailsElement = {IDetailsTags, IDetailsLink, IDetailsSeparator}
26      public List<DetailsElementViewModel> Metadata { get; private set; } = [];
27  
28      public override void InitializeProperties()
29      {
30          var model = _detailsModel.Unsafe;
31          if (model is null)
32          {
33              return;
34          }
35  
36          Title = model.Title ?? string.Empty;
37          Body = model.Body ?? string.Empty;
38          HeroImage = new(model.HeroImage);
39          HeroImage.InitializeProperties();
40  
41          UpdateProperty(nameof(Title));
42          UpdateProperty(nameof(Body));
43          UpdateProperty(nameof(HeroImage));
44  
45          if (model is IExtendedAttributesProvider provider)
46          {
47              if (provider.GetProperties()?.TryGetValue("Size", out var rawValue) == true)
48              {
49                  if (rawValue is int sizeAsInt)
50                  {
51                      Size = (ContentSize)sizeAsInt;
52                  }
53              }
54          }
55  
56          Size ??= ContentSize.Small;
57  
58          UpdateProperty(nameof(Size));
59  
60          var meta = model.Metadata;
61          if (meta is not null)
62          {
63              foreach (var element in meta)
64              {
65                  DetailsElementViewModel? vm = element.Data switch
66                  {
67                      IDetailsSeparator => new DetailsSeparatorViewModel(element, this.PageContext),
68                      IDetailsLink => new DetailsLinkViewModel(element, this.PageContext),
69                      IDetailsCommands => new DetailsCommandsViewModel(element, this.PageContext),
70                      IDetailsTags => new DetailsTagsViewModel(element, this.PageContext),
71                      _ => null,
72                  };
73                  if (vm is not null)
74                  {
75                      vm.InitializeProperties();
76                      Metadata.Add(vm);
77                  }
78              }
79          }
80      }
81  }