Fix image loading using FromStream
This commit is contained in:
parent
8fff39dfc6
commit
272ecdac64
13
.idea/.idea.CORP-MAUI/.idea/deviceManager.xml
generated
Normal file
13
.idea/.idea.CORP-MAUI/.idea/deviceManager.xml
generated
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DeviceTable">
|
||||
<option name="columnSorters">
|
||||
<list>
|
||||
<ColumnSorterState>
|
||||
<option name="column" value="Name" />
|
||||
<option name="order" value="ASCENDING" />
|
||||
</ColumnSorterState>
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
@ -13,7 +13,7 @@
|
||||
HorizontalOptions="Center"
|
||||
VerticalOptions="Center"
|
||||
Color="{StaticResource Primary}"/>
|
||||
|
||||
|
||||
<RefreshView
|
||||
x:Name="PostsRefreshView"
|
||||
IsRefreshing="False"
|
||||
|
||||
@ -55,7 +55,7 @@ public partial class PostsPage
|
||||
{
|
||||
IEnumerable<Task<PostViewModel>> tasks = response.Results.Select(async post =>
|
||||
{
|
||||
PostViewModel vm = new PostViewModel(post);
|
||||
PostViewModel vm = new(post);
|
||||
|
||||
if (!string.IsNullOrEmpty(post.DisplayImageUrl))
|
||||
{
|
||||
@ -63,11 +63,8 @@ public partial class PostsPage
|
||||
{
|
||||
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 fileName = Path.GetFileName(uri.LocalPath);
|
||||
fileName = Path.GetInvalidFileNameChars().Aggregate(fileName, (current, invalidChar) => current.Replace(invalidChar, '_'));
|
||||
|
||||
string cacheFileName = $"post_img_{post.Id}_{fileName}";
|
||||
string cacheFilePath = Path.Combine(FileSystem.CacheDirectory, cacheFileName);
|
||||
@ -91,7 +88,7 @@ public partial class PostsPage
|
||||
{
|
||||
Trace.WriteLine($"[PostsPage] Загрузка изображения: {post.DisplayImageUrl}");
|
||||
byte[]? bytes = await ServiceProvider.ApiService.GetImageBytesAsync(post.DisplayImageUrl);
|
||||
if (bytes != null && bytes.Length > 0)
|
||||
if (bytes is { Length: > 0 })
|
||||
{
|
||||
await File.WriteAllBytesAsync(cacheFilePath, bytes);
|
||||
Trace.WriteLine($"[PostsPage] Сохранено в кэш: {cacheFilePath}");
|
||||
@ -137,13 +134,11 @@ public partial class PostsPage
|
||||
|
||||
private async void OnPostSelected(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (e.CurrentSelection.FirstOrDefault() is PostViewModel selectedPost)
|
||||
{
|
||||
// Навигация на страницу деталей
|
||||
await Navigation.PushAsync(new PostDetailsPage(selectedPost));
|
||||
if (e.CurrentSelection.FirstOrDefault() is not PostViewModel selectedPost) return;
|
||||
// Навигация на страницу деталей
|
||||
await Navigation.PushAsync(new PostDetailsPage(selectedPost));
|
||||
|
||||
// Снимаем выделение
|
||||
PostsCollectionView.SelectedItem = null;
|
||||
}
|
||||
// Снимаем выделение
|
||||
PostsCollectionView.SelectedItem = null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -259,7 +259,7 @@ public class ApiService : IDisposable
|
||||
{
|
||||
try
|
||||
{
|
||||
LoginRequest loginData = new LoginRequest { Email = email, Password = password };
|
||||
LoginRequest loginData = new() { Email = email, Password = password };
|
||||
// Используем относительный путь, так как BaseAddress уже установлен
|
||||
string path = _config.TokenObtainPath.TrimStart('/');
|
||||
|
||||
@ -269,7 +269,7 @@ public class ApiService : IDisposable
|
||||
Trace.WriteLine($"[ApiService] >>> Ожидаемый URL: {_httpClient.BaseAddress}{path}\n");
|
||||
|
||||
// 🔓 Создаем запрос БЕЗ Authorization header (это запрос для получения токена!)
|
||||
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, path)
|
||||
HttpRequestMessage request = new(HttpMethod.Post, path)
|
||||
{
|
||||
Content = JsonContent.Create(loginData)
|
||||
};
|
||||
@ -530,7 +530,7 @@ public class ApiService : IDisposable
|
||||
string relativePath = path.TrimStart('/');
|
||||
|
||||
// Добавляем query параметры
|
||||
if (queryParams != null && queryParams.Any())
|
||||
if (queryParams != null && queryParams.Count != 0)
|
||||
{
|
||||
string query = string.Join("&", queryParams.Select(kvp =>
|
||||
$"{Uri.EscapeDataString(kvp.Key)}={Uri.EscapeDataString(kvp.Value)}"));
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using CORP_MAUI.Models;
|
||||
|
||||
@ -60,7 +61,23 @@ public class PostViewModel : INotifyPropertyChanged
|
||||
get
|
||||
{
|
||||
if (_imageSource != null) return _imageSource;
|
||||
if (!string.IsNullOrEmpty(_localImagePath)) return ImageSource.FromFile(_localImagePath);
|
||||
|
||||
if (!string.IsNullOrEmpty(_localImagePath) && File.Exists(_localImagePath))
|
||||
{
|
||||
// Используем FromStream для надежности, чтобы не блокировать файл
|
||||
// и гарантировать чтение даже из системных папок
|
||||
return ImageSource.FromStream(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
return new FileStream(_localImagePath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Stream.Null;
|
||||
}
|
||||
});
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user