Release 1.0.7.0: Remote Web Panel & Stability Fixes

This commit is contained in:
kitbyte
2026-05-01 22:23:27 +03:00
parent 5273930eef
commit fa753b4a34
76 changed files with 6676 additions and 50 deletions
+16 -1
View File
@@ -109,7 +109,8 @@
<Border Grid.Row="1" BorderBrush="{DynamicResource Border}" BorderThickness="1"
Margin="10 0 10 10"
CornerRadius="5">
<ListBox ItemsSource="{Binding LogList}" SelectionMode="Single"
<Grid>
<ListBox ItemsSource="{Binding LogList}" SelectionMode="Single"
BorderBrush="Transparent" BorderThickness="0"
Background="Transparent"
x:Name="LogList"
@@ -152,6 +153,20 @@
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Top"
Margin="0 4 4 0">
<Button Width="22" Height="22" Padding="4"
Style="{StaticResource IconButton}"
Tag="{StaticResource CopyIcon}"
ToolTip="{DynamicResource mw_copy_logs}"
Command="{Binding CopyLogsCommand}"/>
<Button Width="22" Height="22" Padding="4" Margin="4 0 0 0"
Style="{StaticResource IconButton}"
Tag="{StaticResource ExportIcon}"
ToolTip="{DynamicResource mw_export_logs}"
Command="{Binding ExportLogsCommand}"/>
</StackPanel>
</Grid>
</Border>
@@ -2,6 +2,7 @@
using System.Collections.ObjectModel;
using System.IO;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using WandEnhancer.Core;
@@ -73,6 +74,8 @@ namespace WandEnhancer.View.MainWindow
public RelayCommand RestoreBackupCommand { get; }
public RelayCommand UpdateCommand { get; }
public RelayCommand OpenSettingsCommand { get; }
public RelayCommand CopyLogsCommand { get; }
public RelayCommand ExportLogsCommand { get; }
private void OnFolderPathSelection(object obj)
{
@@ -208,6 +211,64 @@ namespace WandEnhancer.View.MainWindow
MainWindow.Instance.OpenPopup(new SettingsPopup(), Application.Current.FindResource("settings_title") as string);
}
private string BuildLogReport()
{
var builder = new StringBuilder();
foreach (var entry in LogList)
{
builder.AppendLine(entry.Message);
}
return builder.ToString();
}
private void OnCopyLogs(object param)
{
if (LogList.Count == 0)
{
return;
}
try
{
System.Windows.Clipboard.SetText(BuildLogReport());
Log("Logs copied to clipboard.", ELogType.Success);
}
catch (Exception e)
{
Log($"Failed to copy logs: {e.Message}", ELogType.Error);
}
}
private void OnExportLogs(object param)
{
if (LogList.Count == 0)
{
return;
}
using (var dialog = new SaveFileDialog
{
Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*",
FileName = $"wand-enhancer-log-{DateTime.Now:yyyyMMdd-HHmmss}.txt"
})
{
if (dialog.ShowDialog() != DialogResult.OK)
{
return;
}
try
{
File.WriteAllText(dialog.FileName, BuildLogReport());
Log($"Logs exported to '{dialog.FileName}'.", ELogType.Success);
}
catch (Exception e)
{
Log($"Failed to export logs: {e.Message}", ELogType.Error);
}
}
}
public MainWindowVm(MainWindow view)
{
Task.Run(async () => IsUpdateAvailable = await _updater.CheckForUpdates());
@@ -217,6 +278,8 @@ namespace WandEnhancer.View.MainWindow
RestoreBackupCommand = new RelayCommand(OnBackupRestoring);
UpdateCommand = new RelayCommand(OnUpdate);
OpenSettingsCommand = new RelayCommand(OnOpenSettings);
CopyLogsCommand = new RelayCommand(OnCopyLogs);
ExportLogsCommand = new RelayCommand(OnExportLogs);
WeModInfo = Extensions.FindWeMod();
if (WeModInfo == null)
+68 -16
View File
@@ -11,35 +11,87 @@
Foreground="{DynamicResource MutedForeground}"
FontWeight="Medium"
FontSize="13">
<Grid>
<Grid MinWidth="430">
<Grid Visibility="Visible" Margin="0 0 5 0">
<Grid.RowDefinitions>
<RowDefinition Height="27" />
<RowDefinition Height="27" />
<RowDefinition Height="27" />
<RowDefinition Height="27" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" VerticalAlignment="Center" Text="{DynamicResource pv_activate_pro}" />
<CheckBox Grid.Row="0" x:Name="ActivateProBox" HorizontalAlignment="Right" VerticalAlignment="Center"
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" Text="{DynamicResource pv_activate_pro}" />
<CheckBox Grid.Row="0" Grid.Column="1" x:Name="ActivateProBox" HorizontalAlignment="Right" VerticalAlignment="Center"
IsChecked="True" />
<TextBlock Grid.Row="1" VerticalAlignment="Center" Text="{DynamicResource pv_devtools}" />
<CheckBox Grid.Row="1" x:Name="DevToolsHotkeyBox" HorizontalAlignment="Right" VerticalAlignment="Center" />
<TextBlock Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" Text="{DynamicResource pv_devtools}" />
<CheckBox Grid.Row="1" Grid.Column="1" x:Name="DevToolsHotkeyBox" HorizontalAlignment="Right" VerticalAlignment="Center" />
<TextBlock Grid.Row="2" VerticalAlignment="Center" Text="{DynamicResource pv_disable_updates}" />
<CheckBox Grid.Row="2" x:Name="DisableUpdateBox" HorizontalAlignment="Right" VerticalAlignment="Center" />
<TextBlock Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" Text="{DynamicResource pv_disable_updates}" />
<CheckBox Grid.Row="2" Grid.Column="1" x:Name="DisableUpdateBox" HorizontalAlignment="Right" VerticalAlignment="Center" />
<!--<TextBlock
ToolTip="Disable if you want to use older versions separately and manage versions manually via different shortcuts"
ToolTipService.InitialShowDelay="300"
Grid.Row="3" VerticalAlignment="Center">
Apply the patch to new versions <LineBreak /> automatically (hover to see more)
</TextBlock>
<CheckBox Grid.Row="3" x:Name="AutoUpdates" HorizontalAlignment="Right" VerticalAlignment="Center"
IsChecked="True" />-->
<TextBlock Grid.Row="3" Grid.Column="0" VerticalAlignment="Center" Text="{DynamicResource pv_remote_web_panel_preview}" />
<CheckBox Grid.Row="3" Grid.Column="1" x:Name="RemoteWebPanelPreviewBox" HorizontalAlignment="Right" VerticalAlignment="Center" />
<Button Grid.Row="3" Padding="0 5 0 5" Margin="0 15 0 0" Content="{DynamicResource pv_start}"
<Border Grid.Row="4" Grid.ColumnSpan="2" Margin="0 14 0 0" Padding="10"
BorderBrush="{DynamicResource Border}" BorderThickness="1" CornerRadius="4"
Background="{DynamicResource Muted}">
<StackPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" VerticalAlignment="Center"
Foreground="{DynamicResource Foreground}"
Text="{DynamicResource pv_custom_scripts}" />
<Button Grid.Column="1" Padding="10 4" Content="{DynamicResource pv_add_js_scripts}"
Click="OnAddScriptClick" />
</Grid>
<TextBlock Margin="0 7 0 0" FontSize="11" TextWrapping="Wrap"
Opacity="0.8"
Text="{DynamicResource pv_custom_scripts_hint}" />
<ItemsControl x:Name="ScriptList" Margin="0 2 0 0">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Margin="0 6 6 0" Padding="8 3"
Background="{DynamicResource Card}"
BorderBrush="{DynamicResource Border}"
BorderThickness="1"
CornerRadius="3">
<DockPanel LastChildFill="True">
<Button DockPanel.Dock="Right" Tag="{Binding}" Content="x"
BorderThickness="0" Padding="6 0" Margin="6 0 0 0"
Click="OnRemoveScriptClick" />
<TextBlock VerticalAlignment="Center"
Foreground="{DynamicResource Foreground}"
Text="{Binding FileName}" />
</DockPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<TextBlock x:Name="NoScriptsText" Margin="0 7 0 0" FontSize="11"
Opacity="0.7"
Text="{DynamicResource pv_no_custom_scripts}" />
</StackPanel>
</Border>
<Button Grid.Row="5" Grid.ColumnSpan="2" Padding="0 5 0 5" Margin="0 15 0 0" Content="{DynamicResource pv_start}"
Click="OnPatchButtonClick" />
</Grid>
</Grid>
@@ -1,26 +1,75 @@
using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Win32;
using WandEnhancer.Models;
using WandEnhancer.View.Controls;
namespace WandEnhancer.View.Popups
{
public partial class PatchVectorsPopup : UserControl
{
private const string JavaScriptDialogFilter = "JavaScript files (*.js)|*.js";
private const string JavaScriptFileExtension = ".js";
private readonly Action<PatchConfig> _onApply;
private readonly ObservableCollection<SelectedScript> _selectedScripts = new ObservableCollection<SelectedScript>();
public PatchVectorsPopup(Action<PatchConfig> onApply)
{
_onApply = onApply;
InitializeComponent();
ScriptList.ItemsSource = _selectedScripts;
UpdateScriptsEmptyState();
}
private void OnAddScriptClick(object sender, RoutedEventArgs e)
{
var dialog = new OpenFileDialog
{
Filter = JavaScriptDialogFilter,
Multiselect = true,
CheckFileExists = true
};
if (dialog.ShowDialog() != true)
{
return;
}
foreach (var path in dialog.FileNames.Where(IsJavaScriptFile))
{
AddScript(path);
}
if (_selectedScripts.Count > 0)
{
RemoteWebPanelPreviewBox.IsChecked = true;
}
UpdateScriptsEmptyState();
}
private void OnRemoveScriptClick(object sender, RoutedEventArgs e)
{
var button = sender as Button;
var script = button?.Tag as SelectedScript;
if (script == null)
{
return;
}
_selectedScripts.Remove(script);
UpdateScriptsEmptyState();
}
private void OnPatchButtonClick(object sender, RoutedEventArgs e)
{
if (ActivateProBox.IsChecked != true && DisableUpdateBox.IsChecked != true &&
DevToolsHotkeyBox.IsChecked != true)
DevToolsHotkeyBox.IsChecked != true && RemoteWebPanelPreviewBox.IsChecked != true)
{
return;
}
@@ -41,11 +90,51 @@ namespace WandEnhancer.View.Popups
result.Add(EPatchType.DevToolsOnF12);
}
if (RemoteWebPanelPreviewBox.IsChecked == true)
{
result.Add(EPatchType.RemoteWebPanelPreview);
}
_onApply(new PatchConfig
{
PatchTypes = result,
AutoApplyPatches =/* AutoUpdates.IsChecked == true*/ false
CustomScriptPaths = _selectedScripts.Select(script => script.FullPath).ToList(),
AutoApplyPatches = false
});
}
private void AddScript(string path)
{
var fullPath = Path.GetFullPath(path);
if (_selectedScripts.Any(script => string.Equals(script.FullPath, fullPath, StringComparison.OrdinalIgnoreCase)))
{
return;
}
_selectedScripts.Add(new SelectedScript(fullPath));
}
private static bool IsJavaScriptFile(string path)
{
return File.Exists(path) && string.Equals(Path.GetExtension(path), JavaScriptFileExtension, StringComparison.OrdinalIgnoreCase);
}
private void UpdateScriptsEmptyState()
{
NoScriptsText.Visibility = _selectedScripts.Count == 0 ? Visibility.Visible : Visibility.Collapsed;
}
private sealed class SelectedScript
{
public SelectedScript(string fullPath)
{
FullPath = fullPath;
FileName = Path.GetFileName(fullPath);
}
public string FullPath { get; }
public string FileName { get; }
}
}
}