168 lines
6.9 KiB
C#
168 lines
6.9 KiB
C#
using System.Collections.ObjectModel;
|
||
using System.Diagnostics;
|
||
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;
|
||
|
||
var response = await ServiceProvider.ApiService.GetPostsPaginatedAsync(_currentPage);
|
||
|
||
if (refresh)
|
||
{
|
||
_posts.Clear();
|
||
}
|
||
|
||
if (response.Results != null)
|
||
{
|
||
foreach (var post in response.Results)
|
||
{
|
||
Trace.WriteLine($"[PostsPage] Post {post.Id}: '{post.Title}'");
|
||
Trace.WriteLine($" CreatedAt: {post.CreatedAt}");
|
||
Trace.WriteLine($" DisplayImageUrl: {post.DisplayImageUrl}");
|
||
Trace.WriteLine($" Content length: {post.Content?.Length ?? 0}");
|
||
|
||
var vm = new PostViewModel(post);
|
||
_posts.Add(vm);
|
||
|
||
// Асинхронно загружаем изображение с токеном
|
||
_ = Task.Run(async () =>
|
||
{
|
||
if (!string.IsNullOrEmpty(post.DisplayImageUrl))
|
||
{
|
||
try
|
||
{
|
||
// Используем имя файла из URL как ключ кэша
|
||
var uri = new Uri(post.DisplayImageUrl);
|
||
var fileName = Path.GetFileName(uri.LocalPath);
|
||
// Добавляем префикс, чтобы избежать коллизий
|
||
var cacheFileName = $"cache_{post.Id}_{fileName}";
|
||
var cacheFilePath = Path.Combine(FileSystem.CacheDirectory, cacheFileName);
|
||
|
||
// Проверяем кэш
|
||
if (File.Exists(cacheFilePath))
|
||
{
|
||
var fileInfo = new FileInfo(cacheFilePath);
|
||
if (fileInfo.Length > 0)
|
||
{
|
||
Trace.WriteLine($"[PostsPage] >> Image found in cache: {cacheFilePath}");
|
||
await MainThread.InvokeOnMainThreadAsync(() =>
|
||
{
|
||
vm.LocalImagePath = cacheFilePath;
|
||
});
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
// Удаляем пустой файл
|
||
File.Delete(cacheFilePath);
|
||
}
|
||
}
|
||
|
||
// Загружаем, если нет в кэше
|
||
var bytes = await ServiceProvider.ApiService.GetImageBytesAsync(post.DisplayImageUrl);
|
||
if (bytes != null && bytes.Length > 0)
|
||
{
|
||
Trace.WriteLine($"[PostsPage] >> Image loaded ({bytes.Length} bytes), saving to {cacheFilePath}");
|
||
|
||
// Сразу показываем
|
||
await MainThread.InvokeOnMainThreadAsync(() =>
|
||
{
|
||
vm.AuthorizedImageSource = ImageSource.FromStream(() => new MemoryStream(bytes));
|
||
});
|
||
|
||
await File.WriteAllBytesAsync(cacheFilePath, bytes);
|
||
|
||
// Обновляем путь (на всякий случай, для будущего)
|
||
await MainThread.InvokeOnMainThreadAsync(() =>
|
||
{
|
||
vm.LocalImagePath = cacheFilePath;
|
||
});
|
||
}
|
||
else
|
||
{
|
||
Trace.WriteLine($"[PostsPage] >> Image failed to load for post {post.Id} (null/empty)");
|
||
}
|
||
}
|
||
catch(Exception imgEx)
|
||
{
|
||
Trace.WriteLine($"[PostsPage] >> Exception loading image for post {post.Id}: {imgEx.Message}");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
Trace.WriteLine($"[PostsPage] >> No image URL for post {post.Id}");
|
||
}
|
||
});
|
||
}
|
||
}
|
||
}
|
||
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;
|
||
}
|
||
}
|
||
}
|