qwen edit
This commit is contained in:
@@ -19,9 +19,6 @@ public partial class BookshelfViewModel : BaseViewModel
|
|||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _isEmpty;
|
private bool _isEmpty;
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private bool _isRefreshing;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _searchText = string.Empty;
|
private string _searchText = string.Empty;
|
||||||
|
|
||||||
@@ -53,23 +50,22 @@ public partial class BookshelfViewModel : BaseViewModel
|
|||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
public async Task LoadBooksAsync()
|
public async Task LoadBooksAsync()
|
||||||
{
|
{
|
||||||
if (IsBusy) return;
|
|
||||||
IsBusy = true;
|
IsBusy = true;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var books = await _databaseService.GetAllBooksAsync();
|
var books = await _databaseService.GetAllBooksAsync();
|
||||||
|
|
||||||
// Применяем фильтр поиска если есть
|
// Применяем фильтр поиска если есть
|
||||||
if (!string.IsNullOrWhiteSpace(SearchText))
|
if (!string.IsNullOrWhiteSpace(SearchText))
|
||||||
{
|
{
|
||||||
var searchLower = SearchText.ToLowerInvariant();
|
var searchLower = SearchText.ToLowerInvariant();
|
||||||
books = books.Where(b =>
|
books = books.Where(b =>
|
||||||
b.Title.ToLowerInvariant().Contains(searchLower) ||
|
b.Title.ToLowerInvariant().Contains(searchLower) ||
|
||||||
b.Author.ToLowerInvariant().Contains(searchLower)
|
b.Author.ToLowerInvariant().Contains(searchLower)
|
||||||
).ToList();
|
).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
Books.Clear();
|
Books.Clear();
|
||||||
foreach (var book in books)
|
foreach (var book in books)
|
||||||
{
|
{
|
||||||
@@ -87,22 +83,6 @@ public partial class BookshelfViewModel : BaseViewModel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[RelayCommand]
|
|
||||||
public async Task RefreshBooksAsync()
|
|
||||||
{
|
|
||||||
if (IsRefreshing) return;
|
|
||||||
IsRefreshing = true;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await LoadBooksAsync();
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
IsRefreshing = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
public async Task SearchAsync(object? parameter)
|
public async Task SearchAsync(object? parameter)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -65,108 +65,95 @@
|
|||||||
HorizontalTextAlignment="Center" />
|
HorizontalTextAlignment="Center" />
|
||||||
</VerticalStackLayout>
|
</VerticalStackLayout>
|
||||||
|
|
||||||
<!-- Book Collection with PullToRefresh -->
|
<!-- Book Collection -->
|
||||||
<RefreshView Command="{Binding RefreshBooksCommand}"
|
<CollectionView ItemsSource="{Binding Books}"
|
||||||
IsRefreshing="{Binding IsRefreshing}"
|
SelectionMode="None"
|
||||||
IsVisible="{Binding IsEmpty, Converter={StaticResource InvertedBoolConverter}}">
|
Margin="10">
|
||||||
<CollectionView ItemsSource="{Binding Books}"
|
|
||||||
SelectionMode="None"
|
|
||||||
Margin="10">
|
|
||||||
|
|
||||||
<CollectionView.ItemsLayout>
|
<CollectionView.ItemsLayout>
|
||||||
<GridItemsLayout Orientation="Vertical"
|
<GridItemsLayout Orientation="Vertical"
|
||||||
Span="3"
|
Span="3"
|
||||||
HorizontalItemSpacing="10"
|
HorizontalItemSpacing="10"
|
||||||
VerticalItemSpacing="15" />
|
VerticalItemSpacing="15" />
|
||||||
</CollectionView.ItemsLayout>
|
</CollectionView.ItemsLayout>
|
||||||
|
|
||||||
<CollectionView.ItemTemplate>
|
<CollectionView.ItemTemplate>
|
||||||
<DataTemplate x:DataType="models:Book">
|
<DataTemplate x:DataType="models:Book">
|
||||||
<SwipeView>
|
<SwipeView>
|
||||||
<SwipeView.RightItems>
|
<SwipeView.RightItems>
|
||||||
<SwipeItems>
|
<SwipeItems>
|
||||||
<SwipeItem Text="Delete"
|
<SwipeItem Text="Delete"
|
||||||
BackgroundColor="#D32F2F"
|
BackgroundColor="#D32F2F"
|
||||||
Command="{Binding Source={RelativeSource AncestorType={x:Type vm:BookshelfViewModel}}, Path=DeleteBookCommand}"
|
Command="{Binding Source={RelativeSource AncestorType={x:Type vm:BookshelfViewModel}}, Path=DeleteBookCommand}"
|
||||||
CommandParameter="{Binding .}" />
|
CommandParameter="{Binding .}" />
|
||||||
</SwipeItems>
|
</SwipeItems>
|
||||||
</SwipeView.RightItems>
|
</SwipeView.RightItems>
|
||||||
|
|
||||||
<Frame Padding="0"
|
<Frame Padding="0"
|
||||||
CornerRadius="8"
|
CornerRadius="8"
|
||||||
BackgroundColor="#5D4037"
|
BackgroundColor="#5D4037"
|
||||||
HasShadow="True"
|
HasShadow="True"
|
||||||
BorderColor="Transparent">
|
BorderColor="Transparent">
|
||||||
<Frame.GestureRecognizers>
|
<Frame.GestureRecognizers>
|
||||||
<TapGestureRecognizer
|
<TapGestureRecognizer
|
||||||
Command="{Binding Source={RelativeSource AncestorType={x:Type vm:BookshelfViewModel}}, Path=OpenBookCommand}"
|
Command="{Binding Source={RelativeSource AncestorType={x:Type vm:BookshelfViewModel}}, Path=OpenBookCommand}"
|
||||||
CommandParameter="{Binding .}" />
|
CommandParameter="{Binding .}" />
|
||||||
</Frame.GestureRecognizers>
|
</Frame.GestureRecognizers>
|
||||||
|
|
||||||
<Grid RowDefinitions="150,Auto,Auto,Auto" Padding="0">
|
<Grid RowDefinitions="150,Auto,Auto,Auto" Padding="0">
|
||||||
<!-- Cover Image -->
|
<!-- Cover Image -->
|
||||||
<Frame Grid.Row="0"
|
<Frame Grid.Row="0"
|
||||||
Padding="0"
|
Padding="0"
|
||||||
CornerRadius="8,8,0,0"
|
CornerRadius="8,8,0,0"
|
||||||
IsClippedToBounds="True"
|
IsClippedToBounds="True"
|
||||||
HasShadow="False"
|
HasShadow="False"
|
||||||
BorderColor="Transparent">
|
BorderColor="Transparent">
|
||||||
<Image Source="{Binding CoverImage, Converter={StaticResource ByteArrayToImageConverter}}"
|
<Image Source="{Binding CoverImage, Converter={StaticResource ByteArrayToImageConverter}}"
|
||||||
Aspect="AspectFill"
|
Aspect="AspectFill"
|
||||||
HeightRequest="150" />
|
HeightRequest="150" />
|
||||||
</Frame>
|
</Frame>
|
||||||
|
|
||||||
<!-- Progress Bar -->
|
<!-- Progress Bar -->
|
||||||
<Grid Grid.Row="0"
|
<Grid Grid.Row="0"
|
||||||
VerticalOptions="End"
|
VerticalOptions="End"
|
||||||
HeightRequest="4"
|
HeightRequest="4"
|
||||||
BackgroundColor="#44000000">
|
BackgroundColor="#44000000">
|
||||||
<BoxView BackgroundColor="#4CAF50"
|
<BoxView BackgroundColor="#4CAF50"
|
||||||
HorizontalOptions="Start"
|
HorizontalOptions="Start"
|
||||||
WidthRequest="{Binding ReadingProgress, Converter={StaticResource ProgressToWidthConverter}}" />
|
WidthRequest="{Binding ReadingProgress, Converter={StaticResource ProgressToWidthConverter}}" />
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<!-- Title -->
|
||||||
|
<Label Grid.Row="1"
|
||||||
|
Text="{Binding Title}"
|
||||||
|
FontSize="11"
|
||||||
|
FontAttributes="Bold"
|
||||||
|
TextColor="#EFEBE9"
|
||||||
|
LineBreakMode="TailTruncation"
|
||||||
|
MaxLines="2"
|
||||||
|
Padding="5,5,5,0" />
|
||||||
|
|
||||||
|
<!-- Author -->
|
||||||
|
<Label Grid.Row="2"
|
||||||
|
Text="{Binding Author}"
|
||||||
|
FontSize="9"
|
||||||
|
TextColor="#A1887F"
|
||||||
|
LineBreakMode="TailTruncation"
|
||||||
|
MaxLines="1"
|
||||||
|
Padding="5,0,5,2" />
|
||||||
|
|
||||||
|
<!-- Progress Text -->
|
||||||
|
<Label Grid.Row="3"
|
||||||
|
Text="{Binding ProgressText}"
|
||||||
|
FontSize="9"
|
||||||
|
TextColor="#81C784"
|
||||||
|
Padding="5,0,5,5" />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
</Frame>
|
||||||
<!-- Title -->
|
</SwipeView>
|
||||||
<Label Grid.Row="1"
|
</DataTemplate>
|
||||||
Text="{Binding Title}"
|
</CollectionView.ItemTemplate>
|
||||||
FontSize="11"
|
</CollectionView>
|
||||||
FontAttributes="Bold"
|
|
||||||
TextColor="#EFEBE9"
|
|
||||||
LineBreakMode="TailTruncation"
|
|
||||||
MaxLines="2"
|
|
||||||
Padding="5,5,5,0" />
|
|
||||||
|
|
||||||
<!-- Author -->
|
|
||||||
<Label Grid.Row="2"
|
|
||||||
Text="{Binding Author}"
|
|
||||||
FontSize="9"
|
|
||||||
TextColor="#A1887F"
|
|
||||||
LineBreakMode="TailTruncation"
|
|
||||||
MaxLines="1"
|
|
||||||
Padding="5,0,5,2" />
|
|
||||||
|
|
||||||
<!-- Progress Text -->
|
|
||||||
<Label Grid.Row="3"
|
|
||||||
Text="{Binding ProgressText}"
|
|
||||||
FontSize="9"
|
|
||||||
TextColor="#81C784"
|
|
||||||
Padding="5,0,5,5" />
|
|
||||||
</Grid>
|
|
||||||
</Frame>
|
|
||||||
</SwipeView>
|
|
||||||
</DataTemplate>
|
|
||||||
</CollectionView.ItemTemplate>
|
|
||||||
</CollectionView>
|
|
||||||
</RefreshView>
|
|
||||||
|
|
||||||
<!-- Loading Indicator -->
|
|
||||||
<ActivityIndicator IsRunning="{Binding IsBusy}"
|
|
||||||
IsVisible="{Binding IsBusy}"
|
|
||||||
Color="#FF8A65"
|
|
||||||
VerticalOptions="Center"
|
|
||||||
HorizontalOptions="Center"
|
|
||||||
HeightRequest="50"
|
|
||||||
WidthRequest="50" />
|
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<!-- Bottom Shelf / Action Bar -->
|
<!-- Bottom Shelf / Action Bar -->
|
||||||
@@ -208,4 +195,4 @@
|
|||||||
Command="{Binding OpenCalibreLibraryCommand}" />
|
Command="{Binding OpenCalibreLibraryCommand}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</ContentPage>
|
</ContentPage>
|
||||||
|
|||||||
@@ -16,10 +16,14 @@ public partial class BookshelfPage : ContentPage
|
|||||||
BindingContext = viewModel;
|
BindingContext = viewModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async void OnAppearing()
|
protected override void OnAppearing()
|
||||||
{
|
{
|
||||||
base.OnAppearing();
|
base.OnAppearing();
|
||||||
await _viewModel.LoadBooksCommand.ExecuteAsync(null);
|
// Загружаем книги только если коллекция пуста
|
||||||
|
if (_viewModel.Books.Count == 0)
|
||||||
|
{
|
||||||
|
_ = _viewModel.LoadBooksCommand.ExecuteAsync(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void OnMenuClicked(object? sender, EventArgs e)
|
private async void OnMenuClicked(object? sender, EventArgs e)
|
||||||
|
|||||||
Reference in New Issue
Block a user