corp-app/CORP-MAUI/ViewModels/ProfileViewModel.cs

201 lines
7.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.ComponentModel;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Windows.Input;
using CORP_MAUI.Models;
using CORP_MAUI.Pages;
using CORP_MAUI.Services;
namespace CORP_MAUI.ViewModels;
public class ProfileViewModel : INotifyPropertyChanged
{
private User? _user;
private bool _isLoading;
public ProfileViewModel()
{
LoadProfileCommand = new Command(async () => await LoadProfileAsync());
LogoutCommand = new Command(async () => await LogoutAsync());
}
public User? User
{
get => _user;
set
{
_user = value;
OnPropertyChanged();
OnPropertyChanged(nameof(FullName));
OnPropertyChanged(nameof(Username));
OnPropertyChanged(nameof(Email));
OnPropertyChanged(nameof(Position));
OnPropertyChanged(nameof(Department));
OnPropertyChanged(nameof(StatusText));
OnPropertyChanged(nameof(StatusColor));
OnPropertyChanged(nameof(Skills));
OnPropertyChanged(nameof(HasSkills));
OnPropertyChanged(nameof(DisplayImageSource)); // Обновляем изображение при изменении пользователя
}
}
public bool IsLoading
{
get => _isLoading;
set
{
_isLoading = value;
OnPropertyChanged();
}
}
// Wrappers for UI binding
public string FullName => _user?.FullName ?? "Загрузка...";
public string Username => _user != null ? $"@{_user.Username}" : "";
public string Email => _user?.Email ?? "-";
public string Position => _user?.PositionName ?? "-";
public string Department => _user?.DepartmentName ?? "-";
public bool IsOnline => _user?.IsOnline ?? false;
public string StatusText => IsOnline ? "В сети" : "Не в сети";
public Color StatusColor => IsOnline ? Colors.LimeGreen : Colors.Gray;
public List<Skill> Skills => _user?.Skills ?? new List<Skill>();
public bool HasSkills => Skills.Any();
// Image Logic
public ImageSource? DisplayImageSource
{
get
{
// Используем DisplayAvatarSource из модели User (работает с файловым кэшем)
if (_user != null)
{
return _user.DisplayAvatarSource;
}
// Default placeholder
return ImageSource.FromFile("dotnet_bot.png");
}
}
public ICommand LoadProfileCommand { get; }
public ICommand LogoutCommand { get; }
public async Task LoadProfileAsync()
{
if (IsLoading) return;
IsLoading = true;
try
{
Trace.WriteLine("[ProfileViewModel] >>> Начало загрузки профиля");
User? loadedUser = await ServiceProvider.ApiService.GetCurrentUserAsync();
if (loadedUser != null)
{
Trace.WriteLine($"[ProfileViewModel] ✅ Пользователь загружен: {loadedUser.FullName}");
User = loadedUser;
try
{
Trace.WriteLine("[ProfileViewModel] >>> Загрузка аватара");
await LoadAvatarAsync();
Trace.WriteLine("[ProfileViewModel] ✅ Аватар загружен успешно");
}
catch (Exception avatarEx)
{
Trace.WriteLine($"[ProfileViewModel] ⚠️ Ошибка загрузки аватара (не критично): {avatarEx.Message}");
// Ошибка загрузки аватара не критична - продолжаем работу
}
}
else
{
Trace.WriteLine("[ProfileViewModel] ❌ loadedUser == null");
Page? mainPage = Application.Current?.Windows.FirstOrDefault()?.Page;
if (mainPage != null)
await mainPage.DisplayAlert("Ошибка", "Не удалось загрузить профиль", "OK");
}
}
catch (Exception ex)
{
Trace.WriteLine($"[ProfileViewModel] ❌ Исключение при загрузке профиля:");
Trace.WriteLine($" Type: {ex.GetType().Name}");
Trace.WriteLine($" Message: {ex.Message}");
Trace.WriteLine($" StackTrace: {ex.StackTrace}");
Page? mainPage = Application.Current?.Windows.FirstOrDefault()?.Page;
if (mainPage != null)
await mainPage.DisplayAlert("Ошибка", $"Не удалось загрузить профиль: {ex.Message}", "OK");
}
finally
{
IsLoading = false;
Trace.WriteLine("[ProfileViewModel] <<< Завершение загрузки профиля");
}
}
private async Task LoadAvatarAsync()
{
if (_user == null)
{
Trace.WriteLine("[ProfileViewModel] Нет пользователя для загрузки аватара");
return;
}
try
{
Trace.WriteLine($"[ProfileViewModel] >>> Загрузка аватара для {_user.FullName}, URL: {_user.DisplayAvatarUrl}");
// Используем централизованный метод загрузки аватара
await ServiceProvider.ApiService.LoadUserAvatarAsync(_user);
Trace.WriteLine($"[ProfileViewModel] IsAvatarLoaded: {_user.IsAvatarLoaded}, CachedPath: {_user.CachedAvatarFilePath}");
// Обновляем UI на главном потоке
await MainThread.InvokeOnMainThreadAsync(() =>
{
OnPropertyChanged(nameof(DisplayImageSource));
});
Trace.WriteLine("[ProfileViewModel] ✅ Аватар загружен и UI обновлен");
}
catch (Exception ex)
{
Trace.WriteLine($"[ProfileViewModel] ❌ Ошибка загрузки аватара: {ex.Message}");
// Ошибка загрузки аватара не критична
}
}
private async Task LogoutAsync()
{
Page? mainPage = Application.Current?.Windows.FirstOrDefault()?.Page;
if (mainPage == null) return;
bool result = await mainPage.DisplayAlert("Выход", "Вы уверены, что хотите выйти?", "Да", "Нет");
if (result)
{
try
{
await ServiceProvider.ApiService.UpdateStatusAsync(false);
await ServiceProvider.WebSocketService.DisconnectAsync();
ServiceProvider.ApiService.Logout();
SecureStorage.Remove("user_id");
SecureStorage.Remove("username");
if (Application.Current?.Windows.Count > 0)
{
Application.Current.Windows[0].Page = new NavigationPage(new LoginPage());
}
}
catch(Exception ex)
{
await mainPage.DisplayAlert("Ошибка", $"Ошибка при выходе: {ex.Message}", "OK");
}
}
}
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string? name = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}