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

Add Extensions page to Settings UI #18559

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

carlos-zamora
Copy link
Member

@carlos-zamora carlos-zamora commented Feb 11, 2025

Summary of the Pull Request

Adds an Extensions page to the Settings UI. This lets you enable/disable extensions and see how they affect your settings (i.e. adding/modifying profiles and adding color schemes). This page is specifically designed for fragment extensions, but can be expanded on in the future as we develop a more advanced extensions model.

Detailed Description of the Pull Request / Additional comments

  • Settings Model changes:
    • FragmentSettings represents a parsed json fragment extension.
    • FragmentProfileEntry and FragmentColorSchemeEntry are used to track profiles and color schemes added/modified
  • Editor changes - view models:
    • ExtensionsViewModel operates as the main view model for the page.
    • FragmentProfileViewModel and FragmentColorSchemeViewModel are used to reference specific components of fragments. They also provide support for navigating to the linked profile or color scheme via the settings UI!
    • ExtensionPackageViewModel is a VM for a group of extensions exposed by a single source. This is mainly needed because a single source can have multiple JSON fragments in it. This is used for the navigators on the main page. Can be extended to provide additional information (i.e. package logo, package name, etc.)
  • Editor changes - views:
    • Extensions.xaml uses a lot of data templates. These are reused in ItemsControls to display extension components.

Follow-ups

  • Expose dynamic profile generators and allow management over them
  • Collect and display some package metadata (i.e. icon, package name, etc.) for fragment extensions added from an AppExtension
    • include a deep link to the settings app so you can manage the package
  • Streamline a process for adding extensions from the new page

@carlos-zamora

This comment was marked as outdated.

@carlos-zamora
Copy link
Member Author

carlos-zamora commented Feb 11, 2025

Remaining work

  • "TODO CARLOS" littered throughout code
  • Test stability (i.e. add/remove fragments, hide/remove components added by fragments, etc.)
  • Replace "Active Extensions" Expanders with Navigators. In sub pages, include same "Modified Profiles", "Added Profiles" and "Added Color Schemes" along with full JSON. Probably include other metadata (i.e. fragment path)
    • That said, keep those sections in the initial page! It's nice to see a full overview of what was modified all on one page
  • Polish "disclaimer" at the top of extensions page
    • investigate adding more info on creating new fragments and ways to simplify that
    • Skipped over this one. Wasn't sure exactly what we wanted, but it should be super easy to add in if desired

For any reviewers that come along, let me know what you think! 😊 What else would you like to see here?

@carlos-zamora carlos-zamora marked this pull request as ready for review February 19, 2025 20:18
@carlos-zamora
Copy link
Member Author

Demo

Extensions Page v0.2

@@ -59,7 +59,7 @@
<IconSourceElement Grid.Column="0"
Width="16"
Height="16"
IconSource="{x:Bind mtu:IconPathConverter.IconSourceWUX(Icon), Mode=OneTime}" />
IconSource="{x:Bind mtu:IconPathConverter.IconSourceWUX(EvaluatedIcon), Mode=OneTime}" />
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Admittedly, a drive by. Happy to pull this out into a separate PR if desired.

@@ -1199,7 +1199,7 @@
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Had to update this style a bit to enable functionality for showing "Disabled" on the right side when an extension was disabled.

The way I made that work is that we have a 2-column grid. We need the grid to take up the entire horizontal content, so we need to set HorizontalContentAlignmen to stretch

<!-- TODO CARLOS: Icon -->
<!-- TODO GH #18281: Icon -->
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 This one's on me 😅

@@ -227,6 +227,45 @@
</Setter>
</Style>

<!-- A basic setting container displaying immutable text as content -->
<Style x:Key="SettingContainerWithTextContent"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Used to display the Scope for an extension. Also allowed me to apply the SecondaryTextBlockStyle to the text shown on the right side (aka the value of Scope)

Comment on lines +95 to +102
if (_DisabledProfileSources)
{
globals->_DisabledProfileSources = winrt::single_threaded_vector<hstring>();
for (const auto& src : *_DisabledProfileSources)
{
globals->_DisabledProfileSources->Append(src);
}
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Surprised we never copied these over! It's ok though! We didn't have a way for users to modify DisabledProfileSources via the SUI, so this never was a problem!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines +130 to +173
for (const auto&& entry : fragExt.ModifiedProfilesView())
{
// Ensure entry successfully modifies a profile before creating and registering the object
if (const auto& deducedProfile = _settings.FindProfile(entry.ProfileGuid()))
{
auto vm = winrt::make<FragmentProfileViewModel>(entry, fragExt, deducedProfile);
currentProfilesModified.push_back(vm);
if (extensionEnabled)
{
profilesModifiedTotal.push_back(vm);
}
}
}

for (const auto&& entry : fragExt.NewProfilesView())
{
// Ensure entry successfully points to a profile before creating and registering the object.
// The profile may have been removed by the user.
if (const auto& deducedProfile = _settings.FindProfile(entry.ProfileGuid()))
{
auto vm = winrt::make<FragmentProfileViewModel>(entry, fragExt, deducedProfile);
currentProfilesAdded.push_back(vm);
if (extensionEnabled)
{
profilesAddedTotal.push_back(vm);
}
}
}

for (const auto&& entry : fragExt.ColorSchemesView())
{
for (const auto& schemeVM : _colorSchemesPageVM.AllColorSchemes())
{
if (schemeVM.Name() == entry.ColorSchemeName())
{
auto vm = winrt::make<FragmentColorSchemeViewModel>(entry, fragExt, schemeVM);
currentColorSchemesAdded.push_back(vm);
if (extensionEnabled)
{
colorSchemesAddedTotal.push_back(vm);
}
}
}
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm only displaying the ones that were added successfully and point to something that already exists.

Long-term, do we want to do more here? Perhaps show the ones that weren't added successfully? I'm just not sure what the next steps would be and how we would want to approach this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants