191 lines
7.1 KiB
C#
191 lines
7.1 KiB
C#
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
|
||
{
|
||
// Используем централизованный метод загрузки аватара
|
||
await ServiceProvider.ApiService.LoadUserAvatarAsync(_user);
|
||
OnPropertyChanged(nameof(DisplayImageSource));
|
||
Trace.WriteLine("[ProfileViewModel] ✅ Аватар загружен");
|
||
}
|
||
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));
|
||
}
|
||
|