Skip to content

Commit 2d02fc6

Browse files
hez2010yaira2
andauthored
Feature: Lazily loading themes to improve startup time (#10329)
* Enable dynamic PGO * Lazy load other themes * Fix indents * Fix tab indents * Fix tab indents in xaml * Mvvm * Fix a bug where selected theme being duplicated in the list * Use x:Bind where possible * Add an automation text for loading progress * Fix tab indents * Update src/Files.App/Views/SettingsPages/Appearance.xaml * CR * Update Appearance.xaml Co-authored-by: Yair Aichenbaum <[email protected]>
1 parent e18f08a commit 2d02fc6

19 files changed

+199
-154
lines changed

src/Files.App/App.xaml.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,6 @@ await Task.WhenAll(
207207
await Task.WhenAll(
208208
TerminalController.InitializeAsync(),
209209
JumpList.InitializeAsync(),
210-
ExternalResourcesHelper.LoadOtherThemesAsync(),
211210
ContextFlyoutItemHelper.CachedNewContextMenuEntries
212211
);
213212
});
@@ -464,4 +463,4 @@ public static AppWindow GetAppWindow(Window w)
464463

465464
public static IntPtr WindowHandle { get; private set; }
466465
}
467-
}
466+
}

src/Files.App/Dialogs/DynamicDialog.xaml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,19 @@
77
xmlns:i="using:Microsoft.Xaml.Interactivity"
88
xmlns:icore="using:Microsoft.Xaml.Interactions.Core"
99
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
10-
Title="{Binding TitleText, Mode=OneWay}"
10+
Title="{x:Bind ViewModel.TitleText, Mode=OneWay}"
1111
CloseButtonClick="ContentDialog_CloseButtonClick"
12-
CloseButtonText="{Binding CloseButtonText, Mode=OneWay}"
12+
CloseButtonText="{x:Bind ViewModel.CloseButtonText, Mode=OneWay}"
1313
CornerRadius="{StaticResource OverlayCornerRadius}"
1414
DefaultButton="Primary"
15-
IsPrimaryButtonEnabled="{Binding IsPrimaryButtonEnabled, Mode=OneWay}"
16-
IsSecondaryButtonEnabled="{Binding IsSecondaryButtonEnabled, Mode=OneWay}"
15+
IsPrimaryButtonEnabled="{x:Bind ViewModel.IsPrimaryButtonEnabled, Mode=OneWay}"
16+
IsSecondaryButtonEnabled="{x:Bind ViewModel.IsSecondaryButtonEnabled, Mode=OneWay}"
1717
KeyDown="ContentDialog_KeyDown"
1818
PrimaryButtonClick="ContentDialog_PrimaryButtonClick"
19-
PrimaryButtonText="{Binding PrimaryButtonText, Mode=OneWay}"
19+
PrimaryButtonText="{x:Bind ViewModel.PrimaryButtonText, Mode=OneWay}"
2020
RequestedTheme="{x:Bind helpers:ThemeHelper.RootTheme}"
2121
SecondaryButtonClick="ContentDialog_SecondaryButtonClick"
22-
SecondaryButtonText="{Binding SecondaryButtonText, Mode=OneWay}"
22+
SecondaryButtonText="{x:Bind ViewModel.SecondaryButtonText, Mode=OneWay}"
2323
Style="{StaticResource DefaultContentDialogStyle}"
2424
mc:Ignorable="d">
2525

@@ -36,7 +36,7 @@
3636
HorizontalAlignment="Left"
3737
VerticalAlignment="Center"
3838
x:Load="{x:Bind ViewModel.SubtitleLoad, Mode=OneWay}"
39-
Text="{Binding SubtitleText, Mode=OneWay}"
39+
Text="{x:Bind ViewModel.SubtitleText, Mode=OneWay}"
4040
TextWrapping="WrapWholeWords" />
4141

4242
<!-- The dynamic content control -->
@@ -48,11 +48,11 @@
4848
HorizontalContentAlignment="Stretch"
4949
VerticalContentAlignment="Stretch"
5050
x:Load="{x:Bind ViewModel.DisplayControlLoad, Mode=OneWay}"
51-
Content="{Binding DisplayControl, Mode=OneWay}">
51+
Content="{x:Bind ViewModel.DisplayControl, Mode=OneWay}">
5252
<i:Interaction.Behaviors>
5353
<!-- No need to specify CommandParameter - `e` is passed by default -->
5454
<icore:EventTriggerBehavior EventName="Loaded">
55-
<icore:InvokeCommandAction Command="{Binding DisplayControlOnLoadedCommand, Mode=OneWay}" />
55+
<icore:InvokeCommandAction Command="{x:Bind ViewModel.DisplayControlOnLoadedCommand, Mode=OneWay}" />
5656
</icore:EventTriggerBehavior>
5757
</i:Interaction.Behaviors>
5858
</ContentControl>

src/Files.App/Dialogs/ElevateConfirmDialog.xaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@
2020
<Style BasedOn="{StaticResource AccentButtonStyle}" TargetType="Button">
2121
<Setter Property="ContentTemplate">
2222
<Setter.Value>
23-
<DataTemplate x:DataType="Button">
23+
<DataTemplate x:DataType="ContentDialog">
2424
<StackPanel Orientation="Horizontal" Spacing="5">
2525
<FontIcon FontSize="14" Glyph="&#xEA18;" />
26-
<TextBlock Text="{Binding PrimaryButtonText, ElementName=ConfirmElevationDialog}" />
26+
<TextBlock Text="{x:Bind PrimaryButtonText, Mode=OneWay}" />
2727
</StackPanel>
2828
</DataTemplate>
2929
</Setter.Value>

src/Files.App/Files.App.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
2424
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
2525
<Configurations>Debug;Release;Sideload</Configurations>
26+
<TieredCompilation>true</TieredCompilation>
27+
<TieredPgo>true</TieredPgo>
2628
</PropertyGroup>
2729
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
2830
<DefineConstants>TRACE;DEBUG;NETFX_CORE;DISABLE_XAML_GENERATED_MAIN</DefineConstants>

src/Files.App/Helpers/ExternalResourcesHelper.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using Microsoft.UI.Xaml.Markup;
44
using System;
55
using System.Collections.Generic;
6+
using System.Collections.ObjectModel;
67
using System.Diagnostics;
78
using System.IO;
89
using System.Linq;
@@ -13,7 +14,7 @@ namespace Files.App.Helpers
1314
{
1415
public class ExternalResourcesHelper
1516
{
16-
public List<AppTheme> Themes = new List<AppTheme>()
17+
public readonly ObservableCollection<AppTheme> Themes = new()
1718
{
1819
new AppTheme
1920
{
@@ -71,13 +72,13 @@ public async Task LoadOtherThemesAsync()
7172

7273
private async Task AddThemesAsync(StorageFolder folder)
7374
{
74-
foreach (var file in (await folder.GetFilesAsync()).Where(x => x.FileType == ".xaml"))
75+
foreach (var file in (await folder.GetFilesAsync()).Where(x => string.Equals(x.FileType, ".xaml", StringComparison.InvariantCultureIgnoreCase)))
7576
{
76-
if (!Themes.Exists(t => t.AbsolutePath == file.Path))
77+
if (!Themes.Any(t => t.AbsolutePath == file.Path))
7778
{
7879
Themes.Add(new AppTheme()
7980
{
80-
Name = file.Name.Replace(".xaml", "", StringComparison.Ordinal),
81+
Name = file.Name[..^5],
8182
Path = file.Name,
8283
AbsolutePath = file.Path,
8384
});
@@ -93,6 +94,10 @@ public async Task<bool> TryLoadThemeAsync(AppTheme theme)
9394
if (xaml is not null)
9495
{
9596
App.Current.Resources.MergedDictionaries.Add(xaml);
97+
if (!Themes.Any(t => t.AbsolutePath == theme.AbsolutePath))
98+
{
99+
Themes.Add(theme);
100+
}
96101
return true;
97102
}
98103
return false;
@@ -164,4 +169,4 @@ public class AppTheme
164169
public string Key => $"{Name}";
165170
public bool IsImportedTheme { get; set; }
166171
}
167-
}
172+
}

src/Files.App/Strings/en-US/Resources.resw

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2853,4 +2853,7 @@
28532853
<data name="DeleteShortcutDescription" xml:space="preserve">
28542854
<value>The target destination cannot be found {0}. Do you want to delete this shortcut?</value>
28552855
</data>
2856+
<data name="LoadingThemes" xml:space="preserve">
2857+
<value>Loading Themes</value>
2858+
</data>
28562859
</root>

src/Files.App/UserControls/PathBreadcrumb.xaml

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,23 @@
88
xmlns:helpers="using:Files.App.Helpers"
99
xmlns:local="using:Files.App.UserControls"
1010
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
11+
xmlns:views="using:Files.App.Views"
1112
d:DesignHeight="300"
1213
d:DesignWidth="400"
1314
mc:Ignorable="d">
1415
<UserControl.Resources>
15-
<DataTemplate x:Name="CurrentItem">
16+
<DataTemplate x:Name="CurrentItem" x:DataType="views:PathBoxItem">
1617
<StackPanel
1718
x:Name="ListViewItemContentGrid"
1819
AllowDrop="True"
19-
AutomationProperties.Name="{Binding Title}"
20+
AutomationProperties.Name="{x:Bind Title, Mode=OneWay}"
2021
Background="Transparent"
2122
DragLeave="PathBoxItem_DragLeave"
2223
DragOver="PathBoxItem_DragOver"
2324
Drop="PathBoxItem_Drop"
2425
Orientation="Horizontal"
2526
Spacing="4"
26-
Tag="{Binding Path}">
27+
Tag="{x:Bind Path, Mode=OneWay}">
2728
<Interactivity:Interaction.Behaviors>
2829
<Core:EventTriggerBehavior EventName="PointerEntered">
2930
<Core:ChangePropertyAction PropertyName="Opacity">
@@ -45,29 +46,29 @@
4546
<TextBlock
4647
FontSize="12"
4748
FontWeight="Medium"
48-
Text="{Binding Title}" />
49+
Text="{x:Bind Title, Mode=OneWay}" />
4950
<FontIcon FontSize="12" Glyph="&#xE76C;" />
5051
</StackPanel>
5152
</DataTemplate>
52-
<DataTemplate x:Name="ParentItems">
53+
<DataTemplate x:Name="ParentItems" x:DataType="views:PathBoxItem">
5354
<StackPanel
5455
x:Name="ListViewItemContentGrid"
5556
VerticalAlignment="Center"
5657
AllowDrop="True"
57-
AutomationProperties.Name="{Binding Title}"
58+
AutomationProperties.Name="{x:Bind Title, Mode=OneWay}"
5859
Background="Transparent"
5960
DragLeave="PathBoxItem_DragLeave"
6061
DragOver="PathBoxItem_DragOver"
6162
Drop="PathBoxItem_Drop"
6263
Orientation="Horizontal"
6364
Spacing="4"
64-
Tag="{Binding Path}">
65+
Tag="{x:Bind Path, Mode=OneWay}">
6566
<TextBlock
6667
Padding="0,4"
6768
FontSize="12"
6869
PointerPressed="PathBoxItem_PointerPressed"
6970
Tapped="PathBoxItem_Tapped"
70-
Text="{Binding Title}">
71+
Text="{x:Bind Title, Mode=OneWay}">
7172
<Interactivity:Interaction.Behaviors>
7273
<Core:EventTriggerBehavior EventName="PointerEntered">
7374
<Core:ChangePropertyAction PropertyName="Opacity">

src/Files.App/ViewModels/SettingsViewModels/AppearanceViewModel.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using Microsoft.UI.Xaml;
77
using System;
88
using System.Collections.Generic;
9+
using System.Collections.ObjectModel;
910
using System.Threading.Tasks;
1011

1112
namespace Files.App.ViewModels.SettingsViewModels
@@ -27,8 +28,8 @@ public AppearanceViewModel()
2728
};
2829
}
2930

30-
public List<string> Themes { get; set; }
31-
public List<AppTheme> CustomThemes => App.ExternalResourcesHelper.Themes;
31+
public List<string> Themes { get; private set; }
32+
public ObservableCollection<AppTheme> CustomThemes => App.ExternalResourcesHelper.Themes;
3233

3334
public int SelectedThemeIndex
3435
{
@@ -250,6 +251,17 @@ public bool ShowRecentFilesWidget
250251
}
251252
}
252253

254+
private bool isLoadingThemes;
255+
public bool IsLoadingThemes
256+
{
257+
get => isLoadingThemes;
258+
set
259+
{
260+
isLoadingThemes = value;
261+
OnPropertyChanged();
262+
}
263+
}
264+
253265
public Task OpenThemesFolder()
254266
{
255267
//await CoreApplication.MainView.Dispatcher.YieldAsync(); // WINUI3

src/Files.App/ViewModels/SettingsViewModels/FoldersViewModel.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public FoldersViewModel()
2121
ResetLayoutPreferencesCommand = new RelayCommand(ResetLayoutPreferences);
2222
ShowResetLayoutPreferencesTipCommand = new RelayCommand(() => IsResetLayoutPreferencesTipOpen = true);
2323

24-
SelectedDefaultLayoutModeIndex = (long)DefaultLayoutMode;
24+
SelectedDefaultLayoutModeIndex = (int)DefaultLayoutMode;
2525
}
2626

2727
// Properties
@@ -33,8 +33,8 @@ public bool IsResetLayoutPreferencesTipOpen
3333
set => SetProperty(ref isResetLayoutPreferencesTipOpen, value);
3434
}
3535

36-
private long selectedDefaultLayoutModeIndex;
37-
public long SelectedDefaultLayoutModeIndex
36+
private int selectedDefaultLayoutModeIndex;
37+
public int SelectedDefaultLayoutModeIndex
3838
{
3939
get => selectedDefaultLayoutModeIndex;
4040
set

src/Files.App/ViewModels/SettingsViewModels/PreferencesViewModel.cs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -349,25 +349,6 @@ private async Task AddPage(string path = null)
349349
PagesOnStartupList.Add(new PageOnStartupViewModel(path));
350350
}
351351

352-
public class PageOnStartupViewModel
353-
{
354-
public string Text
355-
{
356-
get
357-
{
358-
if (Path == "Home".GetLocalizedResource())
359-
return "Home".GetLocalizedResource();
360-
if (Path == CommonPaths.RecycleBinPath)
361-
return ApplicationData.Current.LocalSettings.Values.Get("RecycleBin_Title", "Recycle Bin");
362-
return Path;
363-
}
364-
}
365-
366-
public string Path { get; }
367-
368-
internal PageOnStartupViewModel(string path) => Path = path;
369-
}
370-
371352
private void ReloadTerminals(TerminalController controller)
372353
{
373354
dispatcherQueue.EnqueueAsync(() =>
@@ -574,6 +555,25 @@ public void Dispose()
574555
}
575556
}
576557

558+
public class PageOnStartupViewModel
559+
{
560+
public string Text
561+
{
562+
get
563+
{
564+
if (Path == "Home".GetLocalizedResource())
565+
return "Home".GetLocalizedResource();
566+
if (Path == CommonPaths.RecycleBinPath)
567+
return ApplicationData.Current.LocalSettings.Values.Get("RecycleBin_Title", "Recycle Bin");
568+
return Path;
569+
}
570+
}
571+
572+
public string Path { get; }
573+
574+
internal PageOnStartupViewModel(string path) => Path = path;
575+
}
576+
577577
public class AppLanguageItem
578578
{
579579
public string LanguagID { get; set; }

0 commit comments

Comments
 (0)