diff --git a/src/Files.App.Launcher/Files.App.Launcher.vcxproj b/src/Files.App.Launcher/Files.App.Launcher.vcxproj
index 93862737d1f1..87b940ed867a 100644
--- a/src/Files.App.Launcher/Files.App.Launcher.vcxproj
+++ b/src/Files.App.Launcher/Files.App.Launcher.vcxproj
@@ -89,7 +89,7 @@
- _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions);_SILENCE_EXPERIMENTAL_COROUTINE_DEPRECATION_WARNINGS
MultiThreadedDebug
@@ -103,7 +103,7 @@
true
true
- NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions);_SILENCE_EXPERIMENTAL_COROUTINE_DEPRECATION_WARNINGS
MultiThreaded
diff --git a/src/Files.App/Data/Items/EncodingItem.cs b/src/Files.App/Data/Items/EncodingItem.cs
index 51ec61b121e9..361ffe6abe62 100644
--- a/src/Files.App/Data/Items/EncodingItem.cs
+++ b/src/Files.App/Data/Items/EncodingItem.cs
@@ -50,7 +50,7 @@ public EncodingItem(Encoding encoding, string name)
//reference: https://en.wikipedia.org/wiki/Windows_code_page
//East Asian
"shift_jis", //Japanese
- "gb2312", //Simplified Chinese
+ "gb18030", //Simplified Chinese
"big5", //Traditional Chinese
"ks_c_5601-1987", //Korean
diff --git a/src/Files.App/Data/Models/CurrentInstanceViewModel.cs b/src/Files.App/Data/Models/CurrentInstanceViewModel.cs
index ffc6a977f291..f77555489655 100644
--- a/src/Files.App/Data/Models/CurrentInstanceViewModel.cs
+++ b/src/Files.App/Data/Models/CurrentInstanceViewModel.cs
@@ -146,6 +146,20 @@ public bool IsPageTypeLibrary
}
}
+ private string? zipEncodingName;
+ public string? ZipEncodingName
+ {
+ get => zipEncodingName;
+ set => SetProperty(ref zipEncodingName, value);
+ }
+
+ private bool isZipEncodingUndetermined;
+ public bool IsZipEncodingUndetermined
+ {
+ get => isZipEncodingUndetermined;
+ set => SetProperty(ref isZipEncodingUndetermined, value);
+ }
+
public bool CanCopyPathInPage
{
get => !isPageTypeMtpDevice && !isPageTypeRecycleBin && isPageTypeNotHome && !isPageTypeSearchResults && !IsPageTypeReleaseNotes && !IsPageTypeSettings;
diff --git a/src/Files.App/Data/Models/DirectoryPropertiesViewModel.cs b/src/Files.App/Data/Models/DirectoryPropertiesViewModel.cs
index 1109998f2b6a..9845a7fad451 100644
--- a/src/Files.App/Data/Models/DirectoryPropertiesViewModel.cs
+++ b/src/Files.App/Data/Models/DirectoryPropertiesViewModel.cs
@@ -1,6 +1,11 @@
// Copyright (c) Files Community
// Licensed under the MIT License.
+using Files.App.Data.Items;
+using Files.App.Utils.Storage;
+using Microsoft.Extensions.Logging;
+using System.ComponentModel;
+using System.Text;
using System.Windows.Input;
namespace Files.App.ViewModels.UserControls
@@ -9,6 +14,8 @@ public sealed partial class StatusBarViewModel : ObservableObject
{
private IContentPageContext ContentPageContext { get; } = Ioc.Default.GetRequiredService();
private IDevToolsSettingsService DevToolsSettingsService = Ioc.Default.GetRequiredService();
+ private readonly IStorageArchiveService StorageArchiveService = Ioc.Default.GetRequiredService();
+ private CurrentInstanceViewModel? InstanceViewModel => ContentPageContext.ShellPage?.InstanceViewModel;
// The first branch will always be the active one.
public const int ACTIVE_BRANCH_INDEX = 0;
@@ -81,6 +88,26 @@ public string ExtendedStatusInfo
set => SetProperty(ref _ExtendedStatusInfo, value);
}
+ private bool _IsZipEncodingSelectorVisible;
+ public bool IsZipEncodingSelectorVisible
+ {
+ get => _IsZipEncodingSelectorVisible;
+ set => SetProperty(ref _IsZipEncodingSelectorVisible, value);
+ }
+
+ public List ZipEncodingOptions { get; } = EncodingItem.Defaults.ToList();
+
+ private EncodingItem? _SelectedZipEncoding;
+ public EncodingItem? SelectedZipEncoding
+ {
+ get => _SelectedZipEncoding;
+ set
+ {
+ if (SetProperty(ref _SelectedZipEncoding, value) && value is not null)
+ _ = OnZipEncodingChangedAsync(value);
+ }
+ }
+
public bool ShowOpenInIDEButton
{
get
@@ -112,6 +139,24 @@ public StatusBarViewModel()
break;
}
};
+
+ SubscribeToShellPage();
+ ContentPageContext.PropertyChanged += OnContentPageContextPropertyChanged;
+ }
+
+ private void OnContentPageContextPropertyChanged(object? sender, PropertyChangedEventArgs e)
+ {
+ if (e.PropertyName == nameof(ContentPageContext.ShellPage))
+ {
+ UnsubscribeFromInstanceViewModel();
+ SubscribeToShellPage();
+ }
+ }
+
+ private void SubscribeToShellPage()
+ {
+ SubscribeToInstanceViewModel();
+ _ = UpdateZipEncodingStateAsync();
}
public void UpdateGitInfo(bool isGitRepository, string? repositoryPath, BranchItem? head)
@@ -164,5 +209,97 @@ public Task ExecuteDeleteBranch(string? branchName)
{
return GitHelpers.DeleteBranchAsync(_gitRepositoryPath, GitBranchDisplayName, branchName);
}
+
+ public async Task UpdateZipEncodingStateAsync()
+ {
+ var instanceVM = InstanceViewModel;
+ if (instanceVM is null)
+ return;
+
+ if (!instanceVM.IsPageTypeZipFolder)
+ {
+ IsZipEncodingSelectorVisible = false;
+ ZipStorageFolder.CurrentEncoding = null;
+ return;
+ }
+
+ var workingDir = ContentPageContext.ShellPage?.ShellViewModel.WorkingDirectory;
+ if (string.IsNullOrEmpty(workingDir) || !ZipStorageFolder.IsZipPath(workingDir))
+ return;
+
+ try
+ {
+ var isUndetermined = await StorageArchiveService.IsEncodingUndeterminedAsync(workingDir);
+ instanceVM.IsZipEncodingUndetermined = isUndetermined;
+
+ if (!isUndetermined)
+ {
+ IsZipEncodingSelectorVisible = false;
+ return;
+ }
+
+ var detected = await StorageArchiveService.DetectEncodingAsync(workingDir);
+ if (detected is not null)
+ {
+ instanceVM.ZipEncodingName = detected.WebName;
+ EncodingItem? ZipEncodingItem = ZipEncodingOptions.FirstOrDefault(e =>
+ e.Encoding?.WebName.Equals(detected.WebName, StringComparison.OrdinalIgnoreCase) == true);
+ if(ZipEncodingItem == null)
+ {
+ ZipEncodingItem = new EncodingItem(detected, detected.EncodingName);
+ }
+ ZipEncodingOptions.Add(ZipEncodingItem);
+ SelectedZipEncoding = ZipEncodingItem;
+ }
+ else
+ {
+ instanceVM.ZipEncodingName = null;
+ SelectedZipEncoding = ZipEncodingOptions.FirstOrDefault(e => e.Encoding is null);
+ }
+
+ IsZipEncodingSelectorVisible = true;
+ }
+ catch (Exception ex)
+ {
+ App.Logger.LogError(ex, "Error checking zip encoding.");
+ IsZipEncodingSelectorVisible = false;
+ }
+ }
+
+ private async Task OnZipEncodingChangedAsync(EncodingItem encodingItem)
+ {
+ if (ContentPageContext.ShellPage is null)
+ return;
+
+ var workingDir = ContentPageContext.ShellPage.ShellViewModel.WorkingDirectory;
+ if (string.IsNullOrEmpty(workingDir))
+ return;
+
+ ZipStorageFolder.CurrentEncoding = encodingItem.Encoding;
+
+ ContentPageContext.ShellPage.ShellViewModel.RefreshItems(null);
+ }
+
+ internal void SubscribeToInstanceViewModel()
+ {
+ var instanceVM = InstanceViewModel;
+ if (instanceVM is not null)
+ instanceVM.PropertyChanged += OnInstanceViewModelPropertyChanged;
+ }
+
+ internal void UnsubscribeFromInstanceViewModel()
+ {
+ var instanceVM = InstanceViewModel;
+ if (instanceVM is not null)
+ instanceVM.PropertyChanged -= OnInstanceViewModelPropertyChanged;
+ }
+
+ private void OnInstanceViewModelPropertyChanged(object? sender, PropertyChangedEventArgs e)
+ {
+ if (e.PropertyName is nameof(CurrentInstanceViewModel.IsPageTypeZipFolder))
+ {
+ _ = UpdateZipEncodingStateAsync();
+ }
+ }
}
}
diff --git a/src/Files.App/Services/Storage/StorageArchiveService.cs b/src/Files.App/Services/Storage/StorageArchiveService.cs
index 991519dc89ef..3ecd0a9dde89 100644
--- a/src/Files.App/Services/Storage/StorageArchiveService.cs
+++ b/src/Files.App/Services/Storage/StorageArchiveService.cs
@@ -361,7 +361,9 @@ public async Task IsEncodingUndeterminedAsync(string archiveFilePath)
{
using (ZipFile zipFile = new ZipFile(archiveFilePath))
{
- return !zipFile.Cast().All(entry => entry.IsUnicodeText);
+ return !zipFile.Cast().All(
+ entry => entry.IsUnicodeText || entry.Name.All(c => char.IsAscii(c))
+ );
}
}
catch (Exception ex)
diff --git a/src/Files.App/UserControls/StatusBar.xaml b/src/Files.App/UserControls/StatusBar.xaml
index 95d7f9e32fde..510e0611f968 100644
--- a/src/Files.App/UserControls/StatusBar.xaml
+++ b/src/Files.App/UserControls/StatusBar.xaml
@@ -30,6 +30,7 @@
+
@@ -193,10 +194,57 @@
Background="{ThemeResource DividerStrokeColorDefaultBrush}" />
+
+
+