256 lines
11 KiB
XML
256 lines
11 KiB
XML
<Window xmlns="https://github.com/avaloniaui"
|
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
xmlns:controls="clr-namespace:PLib.Desktop.Controls"
|
|
xmlns:icons="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
|
|
xmlns:views="clr-namespace:PLib.Desktop.Views"
|
|
xmlns:vm="clr-namespace:PLib.Desktop.ViewModels"
|
|
x:Class="PLib.Desktop.Views.MainWindow"
|
|
x:DataType="vm:MainWindowViewModel"
|
|
Title="PLib — видеотека"
|
|
Width="1180"
|
|
Height="760"
|
|
MinWidth="640"
|
|
MinHeight="420"
|
|
Background="{DynamicResource PageBackgroundBrush}"
|
|
WindowStartupLocation="CenterScreen">
|
|
|
|
<Window.Resources>
|
|
|
|
<DataTemplate x:Key="SettingsTemplate" DataType="vm:SettingsViewModel">
|
|
<views:SettingsView />
|
|
</DataTemplate>
|
|
|
|
<!-- ======================= Video card ======================= -->
|
|
<DataTemplate x:Key="VideoCardTemplate" DataType="vm:VideoCardViewModel">
|
|
<Button Classes="card" Command="{Binding PlayCommand}" ToolTip.Tip="{Binding FullPath}">
|
|
|
|
<Button.ContextMenu>
|
|
<ContextMenu>
|
|
<MenuItem Header="Воспроизвести" Command="{Binding PlayCommand}" />
|
|
<MenuItem Header="Показать в папке" Command="{Binding RevealCommand}" />
|
|
</ContextMenu>
|
|
</Button.ContextMenu>
|
|
|
|
<Grid RowDefinitions="*,Auto">
|
|
|
|
<!-- Poster frame -->
|
|
<Border Grid.Row="0"
|
|
CornerRadius="9"
|
|
ClipToBounds="True"
|
|
Background="{DynamicResource ThumbnailPlaceholderBrush}">
|
|
<Panel>
|
|
<controls:AsyncImage Source="{Binding ThumbnailPath}"
|
|
DecodeWidth="480"
|
|
PlaceholderBrush="{DynamicResource ThumbnailPlaceholderBrush}" />
|
|
|
|
<!-- Shown until ffmpeg has produced a frame for this file. -->
|
|
<icons:MaterialIcon Kind="FilmstripBoxMultiple"
|
|
Width="30"
|
|
Height="30"
|
|
Opacity="0.35"
|
|
Foreground="{DynamicResource TextTertiaryBrush}"
|
|
HorizontalAlignment="Center"
|
|
VerticalAlignment="Center"
|
|
IsVisible="{Binding IsPending}" />
|
|
|
|
<Border Classes="badge"
|
|
Margin="8"
|
|
HorizontalAlignment="Left"
|
|
VerticalAlignment="Top"
|
|
IsVisible="{Binding QualityText, Converter={x:Static ObjectConverters.IsNotNull}}">
|
|
<TextBlock Text="{Binding QualityText}" />
|
|
</Border>
|
|
|
|
<Border Classes="badge"
|
|
Margin="8"
|
|
HorizontalAlignment="Right"
|
|
VerticalAlignment="Bottom">
|
|
<TextBlock Text="{Binding DurationText}" />
|
|
</Border>
|
|
|
|
<Border Classes="playOverlay" Background="{DynamicResource OverlayBrush}">
|
|
<Border Width="46"
|
|
Height="46"
|
|
CornerRadius="23"
|
|
Background="{DynamicResource AccentBrush}"
|
|
HorizontalAlignment="Center"
|
|
VerticalAlignment="Center">
|
|
<icons:MaterialIcon Kind="Play" Width="24" Height="24" Foreground="White" />
|
|
</Border>
|
|
</Border>
|
|
</Panel>
|
|
</Border>
|
|
|
|
<!-- Caption -->
|
|
<StackPanel Grid.Row="1" Margin="4,10,4,2" Spacing="3">
|
|
<TextBlock Classes="cardTitle" Text="{Binding Title}" />
|
|
<StackPanel Orientation="Horizontal" Spacing="6">
|
|
<TextBlock Classes="cardMeta" Text="{Binding SizeText}" />
|
|
</StackPanel>
|
|
</StackPanel>
|
|
|
|
</Grid>
|
|
</Button>
|
|
</DataTemplate>
|
|
|
|
</Window.Resources>
|
|
|
|
<Grid RowDefinitions="Auto,*,Auto">
|
|
|
|
<!-- ======================= Header ======================= -->
|
|
<Border Grid.Row="0"
|
|
Background="{DynamicResource SurfaceBrush}"
|
|
BorderBrush="{DynamicResource SurfaceBorderBrush}"
|
|
BorderThickness="0,0,0,1"
|
|
Padding="20,14">
|
|
<Grid ColumnDefinitions="Auto,*,Auto" ColumnSpacing="20">
|
|
|
|
<StackPanel Grid.Column="0" Orientation="Horizontal" Spacing="10" VerticalAlignment="Center">
|
|
<Border Width="34"
|
|
Height="34"
|
|
CornerRadius="9"
|
|
Background="{DynamicResource AccentSoftBrush}">
|
|
<icons:MaterialIcon Kind="VideoVintage"
|
|
Width="19"
|
|
Height="19"
|
|
Foreground="{DynamicResource AccentBrush}" />
|
|
</Border>
|
|
<StackPanel VerticalAlignment="Center">
|
|
<TextBlock Classes="sectionTitle" Text="Видеотека" />
|
|
<TextBlock Classes="cardMeta" Text="{Binding Videos.Count, StringFormat='{}{0} видео'}" />
|
|
</StackPanel>
|
|
</StackPanel>
|
|
|
|
<TextBox Grid.Column="1"
|
|
MaxWidth="420"
|
|
HorizontalAlignment="Stretch"
|
|
VerticalAlignment="Center"
|
|
PlaceholderText="Поиск по названию…"
|
|
Text="{Binding SearchText}" />
|
|
|
|
<StackPanel Grid.Column="2" Orientation="Horizontal" Spacing="8" VerticalAlignment="Center">
|
|
|
|
<ComboBox MinWidth="180"
|
|
ItemsSource="{Binding SortOptions}"
|
|
SelectedItem="{Binding SelectedSort}">
|
|
<ComboBox.ItemTemplate>
|
|
<DataTemplate x:DataType="vm:SortOption">
|
|
<TextBlock Text="{Binding Label}" />
|
|
</DataTemplate>
|
|
</ComboBox.ItemTemplate>
|
|
</ComboBox>
|
|
|
|
<Button Command="{Binding ScanCommand}"
|
|
IsEnabled="{Binding !IsScanning}"
|
|
ToolTip.Tip="Пересканировать библиотеку">
|
|
<icons:MaterialIcon Kind="Refresh" Width="17" Height="17" />
|
|
</Button>
|
|
|
|
<Button Command="{Binding ToggleThemeCommand}" ToolTip.Tip="Сменить тему">
|
|
<icons:MaterialIcon Kind="ThemeLightDark" Width="17" Height="17" />
|
|
</Button>
|
|
|
|
<Button Command="{Binding OpenSettingsCommand}" ToolTip.Tip="Настройки">
|
|
<icons:MaterialIcon Kind="CogOutline" Width="17" Height="17" />
|
|
</Button>
|
|
|
|
<Button Classes="Primary" Command="{Binding AddFolderCommand}">
|
|
<StackPanel Orientation="Horizontal" Spacing="7">
|
|
<icons:MaterialIcon Kind="FolderPlusOutline" Width="17" Height="17" />
|
|
<TextBlock Text="Добавить папку" />
|
|
</StackPanel>
|
|
</Button>
|
|
|
|
</StackPanel>
|
|
</Grid>
|
|
</Border>
|
|
|
|
<!-- ======================= Grid ======================= -->
|
|
<Panel Grid.Row="1">
|
|
|
|
<ScrollViewer Padding="20,18" HorizontalScrollBarVisibility="Disabled">
|
|
<ItemsRepeater ItemsSource="{Binding Videos}" ItemTemplate="{StaticResource VideoCardTemplate}">
|
|
<ItemsRepeater.Layout>
|
|
<UniformGridLayout ItemsStretch="Fill"
|
|
MinItemWidth="230"
|
|
MinItemHeight="212"
|
|
MinColumnSpacing="16"
|
|
MinRowSpacing="16" />
|
|
</ItemsRepeater.Layout>
|
|
</ItemsRepeater>
|
|
</ScrollViewer>
|
|
|
|
<!-- Empty state -->
|
|
<StackPanel HorizontalAlignment="Center"
|
|
VerticalAlignment="Center"
|
|
Spacing="14"
|
|
MaxWidth="420"
|
|
IsVisible="{Binding IsEmpty}">
|
|
<icons:MaterialIcon Kind="VideoBoxOff"
|
|
Width="52"
|
|
Height="52"
|
|
Opacity="0.35"
|
|
Foreground="{DynamicResource TextTertiaryBrush}"
|
|
HorizontalAlignment="Center" />
|
|
<TextBlock Classes="sectionTitle"
|
|
HorizontalAlignment="Center"
|
|
Text="Здесь пока пусто" />
|
|
<TextBlock Classes="subtle"
|
|
HorizontalAlignment="Center"
|
|
TextAlignment="Center"
|
|
TextWrapping="Wrap"
|
|
Text="Укажите папку с видеофайлами — PLib пройдётся по ней, соберёт превью и покажет всё карточками." />
|
|
<Button Classes="Primary"
|
|
HorizontalAlignment="Center"
|
|
Command="{Binding AddFolderCommand}"
|
|
Content="Выбрать папку" />
|
|
</StackPanel>
|
|
|
|
</Panel>
|
|
|
|
<!-- ======================= Status bar ======================= -->
|
|
<Border Grid.Row="2"
|
|
Background="{DynamicResource SurfaceBrush}"
|
|
BorderBrush="{DynamicResource SurfaceBorderBrush}"
|
|
BorderThickness="0,1,0,0"
|
|
Padding="20,9">
|
|
<Grid ColumnDefinitions="Auto,*,Auto" ColumnSpacing="14">
|
|
|
|
<ProgressBar Grid.Column="0"
|
|
Width="160"
|
|
VerticalAlignment="Center"
|
|
Minimum="0"
|
|
Maximum="100"
|
|
Value="{Binding ScanProgress}"
|
|
IsIndeterminate="{Binding IsProgressIndeterminate}"
|
|
IsVisible="{Binding IsScanning}" />
|
|
|
|
<TextBlock Grid.Column="1"
|
|
Classes="subtle"
|
|
VerticalAlignment="Center"
|
|
TextTrimming="CharacterEllipsis"
|
|
Text="{Binding StatusText}" />
|
|
|
|
<Button Grid.Column="2"
|
|
Content="Отмена"
|
|
Command="{Binding CancelScanCommand}"
|
|
IsVisible="{Binding IsScanning}" />
|
|
|
|
</Grid>
|
|
</Border>
|
|
|
|
<!-- ======================= Settings panel ======================= -->
|
|
<Panel Grid.Row="0"
|
|
Grid.RowSpan="3"
|
|
Classes="settingsOverlay"
|
|
Classes.open="{Binding IsSettingsOpen}">
|
|
<Button Classes="scrim" Command="{Binding CloseSettingsCommand}" />
|
|
<Border Classes="drawer">
|
|
<ContentControl Content="{Binding SettingsPanel}"
|
|
ContentTemplate="{StaticResource SettingsTemplate}" />
|
|
</Border>
|
|
</Panel>
|
|
|
|
</Grid>
|
|
</Window>
|