UI improvements

This commit is contained in:
whimsical-c4lic0 2026-02-18 01:48:28 -06:00
parent 34ad00ce03
commit ac4061f1ca
7 changed files with 1241 additions and 860 deletions

View File

@ -4,30 +4,113 @@
RequestedThemeVariant="Light" RequestedThemeVariant="Light"
x:Class="OF_DL.Gui.App"> x:Class="OF_DL.Gui.App">
<Application.Resources> <Application.Resources>
<SolidColorBrush x:Key="WindowBackgroundBrush" Color="#EEF3FB" /> <ResourceDictionary>
<SolidColorBrush x:Key="SurfaceBackgroundBrush" Color="#FFFFFF" /> <ResourceDictionary.ThemeDictionaries>
<SolidColorBrush x:Key="SurfaceBorderBrush" Color="#DDE5F3" /> <!-- Light Theme -->
<SolidColorBrush x:Key="PrimaryButtonBackgroundBrush" Color="#2E6EEA" /> <ResourceDictionary x:Key="Light">
<SolidColorBrush x:Key="PrimaryButtonForegroundBrush" Color="#FFFFFF" /> <SolidColorBrush x:Key="WindowBackgroundBrush" Color="#F8FAFC" />
<SolidColorBrush x:Key="SecondaryButtonBackgroundBrush" Color="#FFFFFF" /> <SolidColorBrush x:Key="SurfaceBackgroundBrush" Color="#FFFFFF" />
<SolidColorBrush x:Key="SecondaryButtonForegroundBrush" Color="#1F2A44" /> <SolidColorBrush x:Key="SurfaceBorderBrush" Color="#E2E8F0" />
<SolidColorBrush x:Key="SecondaryButtonBorderBrush" Color="#CFD9EB" />
<SolidColorBrush x:Key="TopBarBackgroundBrush" Color="#DDEAFF" /> <!-- Primary Button -->
<SolidColorBrush x:Key="TopBarBorderBrush" Color="#CFD9EB" /> <SolidColorBrush x:Key="PrimaryButtonBackgroundBrush" Color="#3B82F6" />
<SolidColorBrush x:Key="TopBarTextBrush" Color="#304261" /> <SolidColorBrush x:Key="PrimaryButtonBackgroundHoverBrush" Color="#2563EB" />
<SolidColorBrush x:Key="TextPrimaryBrush" Color="#1F2A44" /> <SolidColorBrush x:Key="PrimaryButtonBackgroundPressedBrush" Color="#1D4ED8" />
<SolidColorBrush x:Key="TextSecondaryBrush" Color="#4A5B78" /> <SolidColorBrush x:Key="PrimaryButtonForegroundBrush" Color="#FFFFFF" />
<SolidColorBrush x:Key="HelpBadgeBackgroundBrush" Color="#EAF0FB" />
<SolidColorBrush x:Key="HelpBadgeBorderBrush" Color="#C5D4EC" /> <!-- Secondary Button -->
<SolidColorBrush x:Key="ErrorTextBrush" Color="#FF5A5A" /> <SolidColorBrush x:Key="SecondaryButtonBackgroundBrush" Color="#FFFFFF" />
<SolidColorBrush x:Key="PreviewBackgroundBrush" Color="#F5F8FE" /> <SolidColorBrush x:Key="SecondaryButtonBackgroundHoverBrush" Color="#F1F5F9" />
<SolidColorBrush x:Key="PreviewBorderBrush" Color="#D8E3F4" /> <SolidColorBrush x:Key="SecondaryButtonBackgroundPressedBrush" Color="#E2E8F0" />
<SolidColorBrush x:Key="DangerSoftBackgroundBrush" Color="#FFE8E8" /> <SolidColorBrush x:Key="SecondaryButtonForegroundBrush" Color="#1E293B" />
<SolidColorBrush x:Key="DangerSoftBorderBrush" Color="#E8C5C5" /> <SolidColorBrush x:Key="SecondaryButtonBorderBrush" Color="#CBD5E1" />
<SolidColorBrush x:Key="DangerButtonBackgroundBrush" Color="#D84E4E" />
<SolidColorBrush x:Key="OverlayBackgroundBrush" Color="#80000000" /> <!-- Top Bar -->
<SolidColorBrush x:Key="ModalBackgroundBrush" Color="#FFFFFF" /> <SolidColorBrush x:Key="TopBarBackgroundBrush" Color="#EFF6FF" />
<SolidColorBrush x:Key="ModalBorderBrush" Color="#DDE5F3" /> <SolidColorBrush x:Key="TopBarBorderBrush" Color="#DBEAFE" />
<SolidColorBrush x:Key="TopBarTextBrush" Color="#1E40AF" />
<!-- Text Colors -->
<SolidColorBrush x:Key="TextPrimaryBrush" Color="#0F172A" />
<SolidColorBrush x:Key="TextSecondaryBrush" Color="#475569" />
<!-- Help Badge -->
<SolidColorBrush x:Key="HelpBadgeBackgroundBrush" Color="#EFF6FF" />
<SolidColorBrush x:Key="HelpBadgeBorderBrush" Color="#BFDBFE" />
<!-- Error -->
<SolidColorBrush x:Key="ErrorTextBrush" Color="#EF4444" />
<!-- Preview/Item Background -->
<SolidColorBrush x:Key="PreviewBackgroundBrush" Color="#F8FAFC" />
<SolidColorBrush x:Key="PreviewBorderBrush" Color="#E2E8F0" />
<!-- Danger Button -->
<SolidColorBrush x:Key="DangerSoftBackgroundBrush" Color="#FEE2E2" />
<SolidColorBrush x:Key="DangerSoftBorderBrush" Color="#FECACA" />
<SolidColorBrush x:Key="DangerButtonBackgroundBrush" Color="#EF4444" />
<SolidColorBrush x:Key="DangerButtonBackgroundHoverBrush" Color="#DC2626" />
<SolidColorBrush x:Key="DangerButtonBackgroundPressedBrush" Color="#B91C1C" />
<!-- Modal -->
<SolidColorBrush x:Key="OverlayBackgroundBrush" Color="#99000000" />
<SolidColorBrush x:Key="ModalBackgroundBrush" Color="#FFFFFF" />
<SolidColorBrush x:Key="ModalBorderBrush" Color="#E2E8F0" />
</ResourceDictionary>
<!-- Dark Theme -->
<ResourceDictionary x:Key="Dark">
<SolidColorBrush x:Key="WindowBackgroundBrush" Color="#0F172A" />
<SolidColorBrush x:Key="SurfaceBackgroundBrush" Color="#1E293B" />
<SolidColorBrush x:Key="SurfaceBorderBrush" Color="#334155" />
<!-- Primary Button -->
<SolidColorBrush x:Key="PrimaryButtonBackgroundBrush" Color="#3B82F6" />
<SolidColorBrush x:Key="PrimaryButtonBackgroundHoverBrush" Color="#2563EB" />
<SolidColorBrush x:Key="PrimaryButtonBackgroundPressedBrush" Color="#1D4ED8" />
<SolidColorBrush x:Key="PrimaryButtonForegroundBrush" Color="#FFFFFF" />
<!-- Secondary Button - Fixed for dark theme -->
<SolidColorBrush x:Key="SecondaryButtonBackgroundBrush" Color="#334155" />
<SolidColorBrush x:Key="SecondaryButtonBackgroundHoverBrush" Color="#475569" />
<SolidColorBrush x:Key="SecondaryButtonBackgroundPressedBrush" Color="#1E293B" />
<SolidColorBrush x:Key="SecondaryButtonForegroundBrush" Color="#F1F5F9" />
<SolidColorBrush x:Key="SecondaryButtonBorderBrush" Color="#475569" />
<!-- Top Bar -->
<SolidColorBrush x:Key="TopBarBackgroundBrush" Color="#1E293B" />
<SolidColorBrush x:Key="TopBarBorderBrush" Color="#334155" />
<SolidColorBrush x:Key="TopBarTextBrush" Color="#93C5FD" />
<!-- Text Colors -->
<SolidColorBrush x:Key="TextPrimaryBrush" Color="#F1F5F9" />
<SolidColorBrush x:Key="TextSecondaryBrush" Color="#94A3B8" />
<!-- Help Badge -->
<SolidColorBrush x:Key="HelpBadgeBackgroundBrush" Color="#1E3A8A" />
<SolidColorBrush x:Key="HelpBadgeBorderBrush" Color="#3B82F6" />
<!-- Error -->
<SolidColorBrush x:Key="ErrorTextBrush" Color="#F87171" />
<!-- Preview/Item Background -->
<SolidColorBrush x:Key="PreviewBackgroundBrush" Color="#0F172A" />
<SolidColorBrush x:Key="PreviewBorderBrush" Color="#334155" />
<!-- Danger Button -->
<SolidColorBrush x:Key="DangerSoftBackgroundBrush" Color="#7F1D1D" />
<SolidColorBrush x:Key="DangerSoftBorderBrush" Color="#991B1B" />
<SolidColorBrush x:Key="DangerButtonBackgroundBrush" Color="#EF4444" />
<SolidColorBrush x:Key="DangerButtonBackgroundHoverBrush" Color="#DC2626" />
<SolidColorBrush x:Key="DangerButtonBackgroundPressedBrush" Color="#B91C1C" />
<!-- Modal -->
<SolidColorBrush x:Key="OverlayBackgroundBrush" Color="#CC000000" />
<SolidColorBrush x:Key="ModalBackgroundBrush" Color="#1E293B" />
<SolidColorBrush x:Key="ModalBorderBrush" Color="#334155" />
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</Application.Resources> </Application.Resources>
<Application.Styles> <Application.Styles>
<fluent:FluentTheme /> <fluent:FluentTheme />

View File

@ -33,20 +33,23 @@ public sealed class ConfigCategoryViewModel : ViewModelBase
FolderPerMessageField = fieldList.FirstOrDefault(field => FolderPerMessageField = fieldList.FirstOrDefault(field =>
string.Equals(field.PropertyName, nameof(Config.FolderPerMessage), StringComparison.Ordinal)); string.Equals(field.PropertyName, nameof(Config.FolderPerMessage), StringComparison.Ordinal));
IEnumerable<ConfigFieldViewModel> visibleFields = IsDownloadBehavior IEnumerable<ConfigFieldViewModel> visibleFields = IsExternal
? fieldList.Where(field => field.PropertyName is not nameof(Config.DownloadOnlySpecificDates) ? fieldList.Where(field => field.PropertyName is not nameof(Config.FFmpegPath)
and not nameof(Config.DownloadDateSelection) and not nameof(Config.FFprobePath))
and not nameof(Config.CustomDate) : IsDownloadBehavior
and not nameof(Config.DownloadVideoResolution)) ? fieldList.Where(field => field.PropertyName is not nameof(Config.DownloadOnlySpecificDates)
: IsPerformance and not nameof(Config.DownloadDateSelection)
? fieldList.Where(field => field.PropertyName is not nameof(Config.LimitDownloadRate) and not nameof(Config.CustomDate)
and not nameof(Config.DownloadLimitInMbPerSec)) and not nameof(Config.DownloadVideoResolution))
: IsFolderStructure : IsPerformance
? fieldList.Where(field => field.PropertyName is not nameof(Config.FolderPerPaidPost) ? fieldList.Where(field => field.PropertyName is not nameof(Config.LimitDownloadRate)
and not nameof(Config.FolderPerPost) and not nameof(Config.DownloadLimitInMbPerSec))
and not nameof(Config.FolderPerPaidMessage) : IsFolderStructure
and not nameof(Config.FolderPerMessage)) ? fieldList.Where(field => field.PropertyName is not nameof(Config.FolderPerPaidPost)
: fieldList; and not nameof(Config.FolderPerPost)
and not nameof(Config.FolderPerPaidMessage)
and not nameof(Config.FolderPerMessage))
: fieldList;
foreach (ConfigFieldViewModel field in visibleFields) foreach (ConfigFieldViewModel field in visibleFields)
{ {
@ -56,6 +59,9 @@ public sealed class ConfigCategoryViewModel : ViewModelBase
public string CategoryName { get; } public string CategoryName { get; }
public bool IsExternal =>
string.Equals(CategoryName, "External", StringComparison.Ordinal);
public bool IsDownloadBehavior => public bool IsDownloadBehavior =>
string.Equals(CategoryName, "Download Behavior", StringComparison.Ordinal); string.Equals(CategoryName, "Download Behavior", StringComparison.Ordinal);

View File

@ -485,7 +485,7 @@ public partial class MainWindowViewModel(
RefreshIgnoredUsersListsCommand.NotifyCanExecuteChanged(); RefreshIgnoredUsersListsCommand.NotifyCanExecuteChanged();
} }
[RelayCommand] [RelayCommand(CanExecute = nameof(CanEditConfig))]
private void EditConfig() private void EditConfig()
{ {
if (CurrentScreen == AppScreen.Config) if (CurrentScreen == AppScreen.Config)
@ -824,6 +824,8 @@ public partial class MainWindowViewModel(
private bool CanLogout() => IsAuthenticated && !IsDownloading; private bool CanLogout() => IsAuthenticated && !IsDownloading;
private bool CanEditConfig() => CurrentScreen != AppScreen.Config;
partial void OnCurrentScreenChanged(AppScreen value) partial void OnCurrentScreenChanged(AppScreen value)
{ {
OnPropertyChanged(nameof(IsLoadingScreen)); OnPropertyChanged(nameof(IsLoadingScreen));
@ -839,6 +841,7 @@ public partial class MainWindowViewModel(
RefreshUsersCommand.NotifyCanExecuteChanged(); RefreshUsersCommand.NotifyCanExecuteChanged();
RefreshIgnoredUsersListsCommand.NotifyCanExecuteChanged(); RefreshIgnoredUsersListsCommand.NotifyCanExecuteChanged();
LogoutCommand.NotifyCanExecuteChanged(); LogoutCommand.NotifyCanExecuteChanged();
EditConfigCommand.NotifyCanExecuteChanged();
} }
partial void OnIsDownloadingChanged(bool value) partial void OnIsDownloadingChanged(bool value)
@ -1649,8 +1652,6 @@ public partial class MainWindowViewModel(
or nameof(Config.NonInteractiveModeListName) or nameof(Config.NonInteractiveModeListName)
or nameof(Config.NonInteractiveModePurchasedTab) or nameof(Config.NonInteractiveModePurchasedTab)
or nameof(Config.DisableBrowserAuth) or nameof(Config.DisableBrowserAuth)
or nameof(Config.FFmpegPath)
or nameof(Config.FFprobePath)
or nameof(Config.DownloadPath) or nameof(Config.DownloadPath)
or nameof(Config.DrmVideoDurationMatchThreshold) or nameof(Config.DrmVideoDurationMatchThreshold)
or nameof(Config.DownloadVideos) or nameof(Config.DownloadVideos)
@ -1672,6 +1673,7 @@ public partial class MainWindowViewModel(
{ {
nameof(Config.DisableBrowserAuth) => "Auth", nameof(Config.DisableBrowserAuth) => "Auth",
nameof(Config.FFmpegPath) => "External", nameof(Config.FFmpegPath) => "External",
nameof(Config.FFprobePath) => "External",
nameof(Config.DownloadAvatarHeaderPhoto) => "Download Media Types", nameof(Config.DownloadAvatarHeaderPhoto) => "Download Media Types",
nameof(Config.DownloadPaidPosts) => "Download Media Types", nameof(Config.DownloadPaidPosts) => "Download Media Types",
@ -1743,7 +1745,7 @@ public partial class MainWindowViewModel(
}; };
private static bool IsLeftColumnCategory(string categoryName) => private static bool IsLeftColumnCategory(string categoryName) =>
categoryName is "Appearance" or "Logging" or "Download Behavior" or "Subscriptions"; categoryName is "Appearance" or "Logging" or "External" or "Download Behavior" or "Subscriptions";
private static bool IsRightColumnCategory(string categoryName) => private static bool IsRightColumnCategory(string categoryName) =>
categoryName is "File Naming" or "Folder Structure" or "Performance"; categoryName is "File Naming" or "Folder Structure" or "Performance";
@ -1753,8 +1755,9 @@ public partial class MainWindowViewModel(
{ {
"Appearance" => 1, "Appearance" => 1,
"Logging" => 2, "Logging" => 2,
"Download Behavior" => 3, "External" => 3,
"Subscriptions" => 4, "Download Behavior" => 4,
"Subscriptions" => 5,
_ => 100 _ => 100
}; };

View File

@ -5,99 +5,144 @@
xmlns:views="using:OF_DL.Gui.Views" xmlns:views="using:OF_DL.Gui.Views"
x:Class="OF_DL.Gui.Views.AboutWindow" x:Class="OF_DL.Gui.Views.AboutWindow"
x:DataType="views:AboutWindow" x:DataType="views:AboutWindow"
Width="760" Width="600"
Height="520" Height="520"
MinWidth="620" MinWidth="550"
MinHeight="440" MinHeight="420"
Title="About OF DL" Title="About OF DL"
Background="{DynamicResource WindowBackgroundBrush}" Background="{DynamicResource WindowBackgroundBrush}"
mc:Ignorable="d"> mc:Ignorable="d">
<Border Margin="14" <Window.Styles>
Padding="16" <Style Selector="Button.link">
Background="{DynamicResource SurfaceBackgroundBrush}" <Setter Property="Background" Value="Transparent" />
BorderBrush="{DynamicResource SurfaceBorderBrush}" <Setter Property="Foreground" Value="{DynamicResource PrimaryButtonBackgroundBrush}" />
BorderThickness="1" <Setter Property="Padding" Value="0" />
CornerRadius="12"> <Setter Property="BorderThickness" Value="0" />
<Grid RowDefinitions="Auto,*,Auto"> <Setter Property="Cursor" Value="Hand" />
<TextBlock Grid.Row="0" </Style>
FontSize="24" <Style Selector="Button.link:pointerover">
FontWeight="SemiBold" <Setter Property="Foreground" Value="{DynamicResource PrimaryButtonBackgroundHoverBrush}" />
Foreground="{DynamicResource TextPrimaryBrush}" </Style>
Text="About OF DL" /> </Window.Styles>
<Grid Grid.Row="1" <Grid Margin="24"
Margin="0,14,0,0" RowDefinitions="Auto,*">
ColumnDefinitions="Auto,*" <TextBlock Grid.Row="0"
RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto"> FontSize="28"
<TextBlock Grid.Row="1" FontWeight="Bold"
Grid.Column="0" Foreground="{DynamicResource TextPrimaryBrush}"
FontWeight="SemiBold" Text="About OF DL"
Foreground="{DynamicResource TextPrimaryBrush}" Margin="0,0,0,20" />
Text="Version:" />
<TextBlock Grid.Row="1"
Grid.Column="1"
Foreground="{DynamicResource TextPrimaryBrush}"
Text="{Binding ProgramVersion}" />
<TextBlock Grid.Row="2" <ScrollViewer Grid.Row="1">
Grid.Column="0" <StackPanel Spacing="16">
FontWeight="SemiBold" <!-- Application Info Section -->
Foreground="{DynamicResource TextPrimaryBrush}" <Border Background="{DynamicResource SurfaceBackgroundBrush}"
Text="Source Code:" /> BorderBrush="{DynamicResource SurfaceBorderBrush}"
<Button Grid.Row="2" BorderThickness="1"
Grid.Column="1" CornerRadius="12"
HorizontalAlignment="Left" Padding="24"
Content="{Binding SourceCodeUrl}" BoxShadow="0 1 3 0 #0F000000, 0 1 2 -1 #0F000000">
Click="OnOpenSourceCodeClick" /> <StackPanel Spacing="12">
<TextBlock FontSize="16"
FontWeight="Bold"
Foreground="{DynamicResource TextPrimaryBrush}"
Text="Application" />
<TextBlock Grid.Row="3" <Grid ColumnDefinitions="140,*" RowDefinitions="Auto,Auto">
Grid.Column="0" <TextBlock Grid.Row="0" Grid.Column="0"
FontWeight="SemiBold" FontWeight="SemiBold"
Foreground="{DynamicResource TextPrimaryBrush}" Foreground="{DynamicResource TextSecondaryBrush}"
Text="FFmpeg Version:" /> Text="Version" />
<TextBlock Grid.Row="3" <TextBlock Grid.Row="0" Grid.Column="1"
Grid.Column="1" Foreground="{DynamicResource TextPrimaryBrush}"
Foreground="{DynamicResource TextPrimaryBrush}" Text="{Binding ProgramVersion}" />
Text="{Binding FfmpegVersion}" />
<TextBlock Grid.Row="4" <TextBlock Grid.Row="1" Grid.Column="0"
Grid.Column="0" Margin="0,10,0,0"
FontWeight="SemiBold" FontWeight="SemiBold"
Foreground="{DynamicResource TextPrimaryBrush}" Foreground="{DynamicResource TextSecondaryBrush}"
Text="FFprobe Version:" /> Text="Source Code" />
<TextBlock Grid.Row="4" <Button Grid.Row="1" Grid.Column="1"
Grid.Column="1" Margin="0,10,0,0"
Foreground="{DynamicResource TextPrimaryBrush}" Classes="link"
Text="{Binding FfprobeVersion}" /> HorizontalAlignment="Left"
Content="{Binding SourceCodeUrl}"
Click="OnOpenSourceCodeClick" />
</Grid>
</StackPanel>
</Border>
<TextBlock Grid.Row="5" <!-- FFmpeg Info Section -->
Grid.Column="0" <Border Background="{DynamicResource SurfaceBackgroundBrush}"
FontWeight="SemiBold" BorderBrush="{DynamicResource SurfaceBorderBrush}"
Foreground="{DynamicResource TextPrimaryBrush}" BorderThickness="1"
Text="FFmpeg License:" /> CornerRadius="12"
<Button Grid.Row="5" Padding="24"
Grid.Column="1" BoxShadow="0 1 3 0 #0F000000, 0 1 2 -1 #0F000000">
HorizontalAlignment="Left" <StackPanel Spacing="12">
Content="{Binding FfmpegLicenseUrl}" <TextBlock FontSize="16"
Click="OnOpenFfmpegLicenseClick" /> FontWeight="Bold"
Foreground="{DynamicResource TextPrimaryBrush}"
Text="External Tools" />
<TextBlock Grid.Row="6" <StackPanel Spacing="12">
Grid.Column="0" <!-- FFmpeg -->
FontWeight="SemiBold" <TextBlock Foreground="{DynamicResource TextPrimaryBrush}"
Foreground="{DynamicResource TextPrimaryBrush}" Text="FFmpeg" />
Text="FFprobe License:" /> <Grid ColumnDefinitions="120,*" RowDefinitions="Auto,Auto" Margin="20,0,0,0">
<Button Grid.Row="6" <TextBlock Grid.Row="0" Grid.Column="0"
Grid.Column="1" FontWeight="SemiBold"
HorizontalAlignment="Left" Foreground="{DynamicResource TextSecondaryBrush}"
Content="{Binding FfprobeLicenseUrl}" Text="Version" />
Click="OnOpenFfprobeLicenseClick" /> <TextBlock Grid.Row="0" Grid.Column="1"
</Grid> Foreground="{DynamicResource TextPrimaryBrush}"
Text="{Binding FfmpegVersion}"
TextWrapping="Wrap" />
<Button Grid.Row="2" <TextBlock Grid.Row="1" Grid.Column="0"
Margin="0,18,0,0" Margin="0,8,0,0"
HorizontalAlignment="Right" FontWeight="SemiBold"
Content="Close" Foreground="{DynamicResource TextSecondaryBrush}"
Click="OnCloseClick" /> Text="License" />
</Grid> <Button Grid.Row="1" Grid.Column="1"
</Border> Margin="0,8,0,0"
Classes="link"
HorizontalAlignment="Left"
Content="{Binding FfmpegLicenseUrl}"
Click="OnOpenFfmpegLicenseClick" />
</Grid>
<!-- FFprobe -->
<TextBlock Foreground="{DynamicResource TextPrimaryBrush}"
Text="FFprobe"
Margin="0,4,0,0" />
<Grid ColumnDefinitions="120,*" RowDefinitions="Auto,Auto" Margin="20,0,0,0">
<TextBlock Grid.Row="0" Grid.Column="0"
FontWeight="SemiBold"
Foreground="{DynamicResource TextSecondaryBrush}"
Text="Version" />
<TextBlock Grid.Row="0" Grid.Column="1"
Foreground="{DynamicResource TextPrimaryBrush}"
Text="{Binding FfprobeVersion}"
TextWrapping="Wrap" />
<TextBlock Grid.Row="1" Grid.Column="0"
Margin="0,8,0,0"
FontWeight="SemiBold"
Foreground="{DynamicResource TextSecondaryBrush}"
Text="License" />
<Button Grid.Row="1" Grid.Column="1"
Margin="0,8,0,0"
Classes="link"
HorizontalAlignment="Left"
Content="{Binding FfprobeLicenseUrl}"
Click="OnOpenFfprobeLicenseClick" />
</Grid>
</StackPanel>
</StackPanel>
</Border>
</StackPanel>
</ScrollViewer>
</Grid>
</Window> </Window>

View File

@ -5,10 +5,10 @@
xmlns:views="using:OF_DL.Gui.Views" xmlns:views="using:OF_DL.Gui.Views"
x:Class="OF_DL.Gui.Views.FaqWindow" x:Class="OF_DL.Gui.Views.FaqWindow"
x:DataType="views:FaqWindow" x:DataType="views:FaqWindow"
Width="760" Width="800"
Height="640" Height="680"
MinWidth="600" MinWidth="650"
MinHeight="500" MinHeight="550"
Title="FAQ" Title="FAQ"
Background="{DynamicResource WindowBackgroundBrush}" Background="{DynamicResource WindowBackgroundBrush}"
mc:Ignorable="d"> mc:Ignorable="d">
@ -17,91 +17,124 @@
<Setter Property="Background" Value="{DynamicResource SurfaceBackgroundBrush}" /> <Setter Property="Background" Value="{DynamicResource SurfaceBackgroundBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource SurfaceBorderBrush}" /> <Setter Property="BorderBrush" Value="{DynamicResource SurfaceBorderBrush}" />
<Setter Property="BorderThickness" Value="1" /> <Setter Property="BorderThickness" Value="1" />
<Setter Property="CornerRadius" Value="10" /> <Setter Property="CornerRadius" Value="12" />
<Setter Property="Padding" Value="14" /> <Setter Property="Padding" Value="20" />
<Setter Property="Margin" Value="0,0,0,10" /> <Setter Property="Margin" Value="0,0,0,16" />
<Setter Property="BoxShadow" Value="0 1 3 0 #0F000000, 0 1 2 -1 #0F000000" />
<Setter Property="Transitions">
<Transitions>
<BoxShadowsTransition Property="BoxShadow" Duration="0:0:0.2" />
</Transitions>
</Setter>
</Style>
<Style Selector="Border.faqCard:pointerover">
<Setter Property="BoxShadow" Value="0 4 6 -1 #19000000, 0 2 4 -1 #0F000000" />
</Style>
<Style Selector="TextBlock.question">
<Setter Property="FontSize" Value="18" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Foreground" Value="{DynamicResource TextPrimaryBrush}" />
<Setter Property="TextWrapping" Value="Wrap" />
</Style>
<Style Selector="TextBlock.answer">
<Setter Property="FontSize" Value="14" />
<Setter Property="Foreground" Value="{DynamicResource TextSecondaryBrush}" />
<Setter Property="TextWrapping" Value="Wrap" />
<Setter Property="LineHeight" Value="22" />
</Style>
<Style Selector="Button.link">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Padding" Value="0" />
<Setter Property="Foreground" Value="{DynamicResource PrimaryButtonBackgroundBrush}" />
<Setter Property="FontWeight" Value="SemiBold" />
<Setter Property="Cursor" Value="Hand" />
<Setter Property="HorizontalAlignment" Value="Left" />
</Style>
<Style Selector="Button.link:pointerover">
<Setter Property="Foreground" Value="{DynamicResource PrimaryButtonBackgroundHoverBrush}" />
</Style>
<Style Selector="Border.codeBlock">
<Setter Property="Background" Value="{DynamicResource PreviewBackgroundBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource PreviewBorderBrush}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="CornerRadius" Value="8" />
<Setter Property="Padding" Value="12" />
<Setter Property="Margin" Value="0,8,0,0" />
</Style> </Style>
</Window.Styles> </Window.Styles>
<Border Margin="14" <Grid Margin="24"
Padding="16" RowDefinitions="Auto,*">
Background="{DynamicResource SurfaceBackgroundBrush}" <!-- Header -->
BorderBrush="{DynamicResource SurfaceBorderBrush}" <TextBlock Grid.Row="0"
BorderThickness="1" FontSize="32"
CornerRadius="12"> FontWeight="Bold"
<Grid RowDefinitions="Auto,Auto,*,Auto"> Foreground="{DynamicResource TextPrimaryBrush}"
<TextBlock Grid.Row="0" Text="Frequently Asked Questions"
FontSize="24" Margin="0,0,0,20" />
FontWeight="SemiBold"
Foreground="{DynamicResource TextPrimaryBrush}"
Text="Frequently Asked Questions" />
<ScrollViewer Grid.Row="2" <!-- FAQ Items -->
Margin="0,14,0,0"> <ScrollViewer Grid.Row="1">
<ItemsControl ItemsSource="{Binding Entries}"> <ItemsControl ItemsSource="{Binding Entries}">
<ItemsControl.ItemTemplate> <ItemsControl.ItemTemplate>
<DataTemplate x:DataType="views:FaqEntry"> <DataTemplate x:DataType="views:FaqEntry">
<Border Classes="faqCard"> <Border Classes="faqCard">
<StackPanel Spacing="8"> <StackPanel Spacing="12">
<TextBlock FontSize="18" <!-- Question -->
FontWeight="SemiBold" <TextBlock Classes="question"
Text="{Binding Question}" />
<!-- Answer Paragraphs -->
<ItemsControl ItemsSource="{Binding Paragraphs}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="x:String">
<TextBlock Classes="answer"
Text="{Binding .}"
Margin="0,0,0,8" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<!-- Links -->
<ItemsControl IsVisible="{Binding HasLinks}"
ItemsSource="{Binding Links}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Spacing="8" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="views:FaqLink">
<Button Classes="link"
Content="{Binding Label}"
ToolTip.Tip="{Binding Url}"
CommandParameter="{Binding Url}"
Click="OnLinkClick" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<!-- Code Snippet -->
<Border IsVisible="{Binding HasCodeSnippet}"
Classes="codeBlock">
<TextBlock Text="{Binding CodeSnippet}"
FontFamily="Consolas,Courier New,monospace"
FontSize="13"
Foreground="{DynamicResource TextPrimaryBrush}" Foreground="{DynamicResource TextPrimaryBrush}"
Text="{Binding Question}"
TextWrapping="Wrap" /> TextWrapping="Wrap" />
</Border>
<ItemsControl ItemsSource="{Binding Paragraphs}"> </StackPanel>
<ItemsControl.ItemTemplate> </Border>
<DataTemplate x:DataType="x:String"> </DataTemplate>
<TextBlock Foreground="{DynamicResource TextSecondaryBrush}" </ItemsControl.ItemTemplate>
Text="{Binding .}" </ItemsControl>
TextWrapping="Wrap" /> </ScrollViewer>
</DataTemplate> </Grid>
</ItemsControl.ItemTemplate>
</ItemsControl>
<ItemsControl IsVisible="{Binding HasLinks}"
ItemsSource="{Binding Links}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="views:FaqLink">
<Button HorizontalAlignment="Left"
Background="Transparent"
BorderThickness="0"
Padding="0"
Foreground="{DynamicResource PrimaryButtonBackgroundBrush}"
FontWeight="SemiBold"
Content="{Binding Label}"
ToolTip.Tip="{Binding Url}"
CommandParameter="{Binding Url}"
Click="OnLinkClick" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Border IsVisible="{Binding HasCodeSnippet}"
Margin="0,2,0,0"
Padding="10"
CornerRadius="8"
Background="{DynamicResource PreviewBackgroundBrush}"
BorderBrush="{DynamicResource PreviewBorderBrush}"
BorderThickness="1">
<TextBlock Text="{Binding CodeSnippet}"
FontFamily="Consolas"
FontSize="12"
Foreground="{DynamicResource TextPrimaryBrush}"
TextWrapping="Wrap" />
</Border>
</StackPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
<Button Grid.Row="3"
Margin="0,18,0,0"
HorizontalAlignment="Right"
Content="Close"
Click="OnCloseClick" />
</Grid>
</Border>
</Window> </Window>

File diff suppressed because it is too large Load Diff

View File

@ -140,7 +140,10 @@ public partial class MainWindow : Window
private void OnFaqClick(object? sender, RoutedEventArgs e) private void OnFaqClick(object? sender, RoutedEventArgs e)
{ {
FaqWindow faqWindow = new(); FaqWindow faqWindow = new()
{
WindowStartupLocation = WindowStartupLocation.CenterOwner
};
faqWindow.Show(this); faqWindow.Show(this);
} }
@ -151,7 +154,10 @@ public partial class MainWindow : Window
return; return;
} }
AboutWindow aboutWindow = new(vm.ProgramVersion, vm.FfmpegVersion, vm.FfprobeVersion); AboutWindow aboutWindow = new(vm.ProgramVersion, vm.FfmpegVersion, vm.FfprobeVersion)
{
WindowStartupLocation = WindowStartupLocation.CenterOwner
};
aboutWindow.Show(this); aboutWindow.Show(this);
} }