158 lines
5.8 KiB
C#
158 lines
5.8 KiB
C#
using System.ComponentModel;
|
|
using System.Diagnostics;
|
|
using System.Runtime.CompilerServices;
|
|
using CORP_MAUI.Models;
|
|
|
|
namespace CORP_MAUI.ViewModels;
|
|
|
|
public class PostViewModel : INotifyPropertyChanged
|
|
{
|
|
public Post Post { get; }
|
|
|
|
public PostViewModel(Post post)
|
|
{
|
|
Post = post;
|
|
// Truncate content for preview
|
|
if (!string.IsNullOrEmpty(Post.Content) && Post.Content.Length > 0)
|
|
{
|
|
if (Post.Content.Length > 100)
|
|
{
|
|
_previewContent = Post.Content.Substring(0, 100) + "...";
|
|
}
|
|
else
|
|
{
|
|
_previewContent = Post.Content;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_previewContent = string.Empty;
|
|
}
|
|
}
|
|
|
|
private string? _localImagePath;
|
|
public string? LocalImagePath
|
|
{
|
|
get => _localImagePath;
|
|
set
|
|
{
|
|
_localImagePath = value;
|
|
OnPropertyChanged();
|
|
OnPropertyChanged(nameof(IsImageVisible));
|
|
OnPropertyChanged(nameof(DisplayImageSource));
|
|
}
|
|
}
|
|
|
|
private ImageSource? _imageSource;
|
|
public ImageSource? AuthorizedImageSource
|
|
{
|
|
get => _imageSource;
|
|
set
|
|
{
|
|
_imageSource = value;
|
|
OnPropertyChanged();
|
|
OnPropertyChanged(nameof(IsImageVisible));
|
|
OnPropertyChanged(nameof(DisplayImageSource));
|
|
}
|
|
}
|
|
|
|
public ImageSource? DisplayImageSource
|
|
{
|
|
get
|
|
{
|
|
// 1. Проверяем установленный _imageSource (для предварительно загруженных)
|
|
if (_imageSource != null) return _imageSource;
|
|
|
|
// 2. Проверяем, есть ли Base64 изображение в Post.Image
|
|
if (Post != null && !string.IsNullOrEmpty(Post.Image))
|
|
{
|
|
// Только если это Base64 - декодируем напрямую
|
|
if (Post.Image.StartsWith("data:image"))
|
|
{
|
|
try
|
|
{
|
|
// Извлекаем Base64 данные из строки "data:image/jpeg;base64,..."
|
|
string base64Data = Post.Image;
|
|
int commaIndex = base64Data.IndexOf(',');
|
|
if (commaIndex > 0)
|
|
{
|
|
base64Data = base64Data.Substring(commaIndex + 1);
|
|
byte[] imageBytes = Convert.FromBase64String(base64Data);
|
|
Trace.WriteLine($"[PostViewModel] ✅ Base64 изображение декодировано ({imageBytes.Length} bytes)");
|
|
return ImageSource.FromStream(() => new MemoryStream(imageBytes));
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Trace.WriteLine($"[PostViewModel] ⚠️ Ошибка декодирования Base64 изображения: {ex.Message}");
|
|
}
|
|
}
|
|
// Если Post.Image содержит URL (не Base64), то он будет обработан через DisplayImageUrl
|
|
// и загружен в PostsPage, после чего попадёт в _localImagePath
|
|
}
|
|
|
|
// 3. Проверяем локальный кеш (для URL изображений, загруженных в PostsPage)
|
|
if (!string.IsNullOrEmpty(_localImagePath) && File.Exists(_localImagePath))
|
|
{
|
|
// Basic check for empty files
|
|
try
|
|
{
|
|
FileInfo fileInfo = new FileInfo(_localImagePath);
|
|
if (fileInfo.Length == 0)
|
|
{
|
|
Trace.WriteLine($"[PostViewModel] ⚠️ Файл изображения пуст: {_localImagePath}");
|
|
return null;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Trace.WriteLine($"[PostViewModel] ⚠️ Ошибка проверки файла: {ex.Message}");
|
|
return null;
|
|
}
|
|
|
|
// Используем FromStream для надежности, чтобы не блокировать файл
|
|
// и гарантировать чтение даже из системных папок
|
|
return ImageSource.FromStream(() =>
|
|
{
|
|
try
|
|
{
|
|
return new FileStream(_localImagePath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Trace.WriteLine($"[PostViewModel] ⚠️ Ошибка чтения изображения {_localImagePath}: {ex.Message}");
|
|
return null;
|
|
}
|
|
});
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public bool IsImageVisible => DisplayImageSource != null;
|
|
|
|
private string _previewContent;
|
|
public string PreviewContent
|
|
{
|
|
get => _previewContent;
|
|
set
|
|
{
|
|
_previewContent = value;
|
|
OnPropertyChanged();
|
|
}
|
|
}
|
|
|
|
// Proxy properties for cleaner XAML binding if needed, or bind to Post.Title directly
|
|
public int Id => Post.Id;
|
|
public string Title => Post.Title;
|
|
public string? AuthorizedImageUrl => Post.DisplayImageUrl;
|
|
|
|
public event PropertyChangedEventHandler? PropertyChanged;
|
|
|
|
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
|
|
{
|
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
|
}
|
|
}
|