corp-app/CORP-MAUI/Pages/PostsPage.xaml.cs

150 lines
5.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections.ObjectModel;
using System.Diagnostics;
using CORP_MAUI.Models;
using CORP_MAUI.ViewModels;
namespace CORP_MAUI.Pages;
public partial class PostsPage
{
private readonly ObservableCollection<PostViewModel> _posts;
private int _currentPage = 1;
private bool _isLoading;
public PostsPage()
{
InitializeComponent();
_posts = new ObservableCollection<PostViewModel>();
PostsCollectionView.ItemsSource = _posts;
}
// Добавляем метод OnAppearing, чтобы обновлять данные при показе страницы, если нужно
protected override void OnAppearing()
{
base.OnAppearing();
if (_posts.Count == 0)
{
_ = LoadPostsAsync();
}
}
private async Task LoadPostsAsync(bool refresh = false)
{
if (_isLoading) return;
_isLoading = true;
if (refresh)
{
_currentPage = 1;
}
try
{
LoadingIndicator.IsVisible = true;
LoadingIndicator.IsRunning = true;
PaginatedResponse<Post> response = await ServiceProvider.ApiService.GetPostsPaginatedAsync(_currentPage);
if (refresh)
{
_posts.Clear();
}
if (response.Results != null)
{
IEnumerable<Task<PostViewModel>> tasks = response.Results.Select(async post =>
{
PostViewModel vm = new PostViewModel(post);
if (!string.IsNullOrEmpty(post.DisplayImageUrl))
{
try
{
Uri uri = new Uri(post.DisplayImageUrl);
// Sanitize filename
string fileName = Path.GetFileName(uri.LocalPath);
foreach (char invalidChar in Path.GetInvalidFileNameChars())
{
fileName = fileName.Replace(invalidChar, '_');
}
string cacheFileName = $"post_img_{post.Id}_{fileName}";
string cacheFilePath = Path.Combine(FileSystem.CacheDirectory, cacheFileName);
bool isCached = false;
// 1. Проверяем кэш
if (File.Exists(cacheFilePath))
{
FileInfo fileInfo = new FileInfo(cacheFilePath);
if (fileInfo.Length > 0)
{
Trace.WriteLine($"[PostsPage] Изображение из кэша: {cacheFilePath}");
vm.LocalImagePath = cacheFilePath;
isCached = true;
}
}
// 2. Если нет в кэше - загружаем
if (!isCached)
{
Trace.WriteLine($"[PostsPage] Загрузка изображения: {post.DisplayImageUrl}");
byte[]? bytes = await ServiceProvider.ApiService.GetImageBytesAsync(post.DisplayImageUrl);
if (bytes != null && bytes.Length > 0)
{
await File.WriteAllBytesAsync(cacheFilePath, bytes);
Trace.WriteLine($"[PostsPage] Сохранено в кэш: {cacheFilePath}");
vm.LocalImagePath = cacheFilePath;
}
}
}
catch(Exception imgEx)
{
Trace.WriteLine($"[PostsPage] Ошибка обработки изображения для поста {post.Id}: {imgEx.Message}");
}
}
return vm;
});
// Ждем загрузки всех изображений перед отображением списка
PostViewModel[] viewModels = await Task.WhenAll(tasks);
foreach (PostViewModel vm in viewModels)
{
_posts.Add(vm);
}
}
}
catch (Exception ex)
{
Trace.WriteLine($"Ошибка загрузки постов: {ex.Message}");
await DisplayAlert("Ошибка", "Не удалось загрузить новости", "OK");
}
finally
{
_isLoading = false;
LoadingIndicator.IsVisible = false;
LoadingIndicator.IsRunning = false;
PostsRefreshView.IsRefreshing = false;
}
}
private async void OnRefreshing(object sender, EventArgs e)
{
await LoadPostsAsync(true);
}
private async void OnPostSelected(object sender, SelectionChangedEventArgs e)
{
if (e.CurrentSelection.FirstOrDefault() is PostViewModel selectedPost)
{
// Навигация на страницу деталей
await Navigation.PushAsync(new PostDetailsPage(selectedPost));
// Снимаем выделение
PostsCollectionView.SelectedItem = null;
}
}
}