corp-app/CORP-MAUI/AppShell.xaml.cs

232 lines
9.7 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.Diagnostics;
using CORP_MAUI.Pages;
namespace CORP_MAUI;
public partial class AppShell : Shell
{
// Порог ширины для переключения на вертикальное меню (в пикселях)
private const double WideScreenThreshold = 768;
private bool _isDesktopMode;
public AppShell()
{
try
{
Trace.WriteLine("=== APPSHELL CONSTRUCTOR START ===");
Trace.WriteLine("[AppShell] >>> Вызов InitializeComponent");
InitializeComponent();
Trace.WriteLine("[AppShell] >>> InitializeComponent завершен");
Trace.WriteLine("[AppShell] >>> Регистрация маршрутов");
// Регистрация маршрутов для навигации
Routing.RegisterRoute(nameof(ChatPage), typeof(ChatPage));
Routing.RegisterRoute(nameof(DepartmentDetailsPage), typeof(DepartmentDetailsPage));
Routing.RegisterRoute(nameof(EmployeeProfilePage), typeof(EmployeeProfilePage));
Trace.WriteLine("[AppShell] ✅ AppShell инициализирован");
Trace.WriteLine("=== APPSHELL CONSTRUCTOR END ===");
// Устанавливаем начальный режим меню
UpdateLayoutMode();
// Инициализация без ожидания (так await нельзя из синхронного конструктора)
_ = InitializeAsync();
}
catch (Exception ex)
{
Trace.WriteLine("=== APPSHELL CONSTRUCTOR ERROR ===");
Trace.WriteLine($"[AppShell] ❌ Тип ошибки: {ex.GetType().FullName}");
Trace.WriteLine($"[AppShell] ❌ Сообщение: {ex.Message}");
Trace.WriteLine($"[AppShell] ❌ StackTrace: {ex.StackTrace}");
if (ex.InnerException != null)
{
Trace.WriteLine($"[AppShell] ❌ InnerException: {ex.InnerException.Message}");
Trace.WriteLine($"[AppShell] ❌ InnerException StackTrace: {ex.InnerException.StackTrace}");
}
// Показываем ошибку в диалоге
Task.Run(async () =>
{
await Task.Delay(100);
await MainThread.InvokeOnMainThreadAsync(async () =>
{
Page? mainPage = Application.Current?.Windows.FirstOrDefault()?.Page;
if (mainPage != null)
{
await mainPage.DisplayAlert("Ошибка AppShell",
$"Ошибка инициализации AppShell:\n{ex.Message}\n\nStackTrace:\n{ex.StackTrace}", "OK");
}
});
});
throw;
}
}
private async Task InitializeAsync()
{
try
{
Trace.WriteLine("[AppShell] >>> Начало InitializeAsync");
// Инициализация сервисов (если они не инициализированы)
ServiceProvider.Initialize();
Trace.WriteLine($"[AppShell] IsAuthenticated: {ServiceProvider.ApiService.IsAuthenticated}");
// Проверяем, авторизован ли пользователь (токены загружаются автоматически в ApiService)
if (ServiceProvider.ApiService.IsAuthenticated)
{
// Получаем токен для WebSocket
string? accessToken = await SecureStorage.GetAsync("api.jwt_access");
Trace.WriteLine($"[AppShell] Access token exists: {!string.IsNullOrEmpty(accessToken)}");
Trace.WriteLine($"[AppShell] WebSocket connected: {ServiceProvider.WebSocketService.IsConnected}");
if (!string.IsNullOrEmpty(accessToken) && !ServiceProvider.WebSocketService.IsConnected)
{
Trace.WriteLine("[AppShell] >>> Подключение WebSocket из AppShell");
// Подключаем WebSocket только если его еще не подключен
await ServiceProvider.WebSocketService.ConnectAsync(accessToken);
Trace.WriteLine("[AppShell] ✅ WebSocket подключен из AppShell");
}
else if (ServiceProvider.WebSocketService.IsConnected)
{
Trace.WriteLine("[AppShell] WebSocket уже подключен, пропускаем");
}
}
else
{
Trace.WriteLine("[AppShell] ⚠️ Пользователь не авторизован");
}
Trace.WriteLine("[AppShell] ✅ InitializeAsync завершен");
}
catch (Exception ex)
{
Trace.WriteLine($"[AppShell] ❌ Ошибка InitializeAsync: {ex.Message}");
Trace.WriteLine($"[AppShell] StackTrace: {ex.StackTrace}");
await DisplayAlert("Ошибка", $"Ошибка инициализации: {ex.Message}", "OK");
}
}
protected override void OnSizeAllocated(double width, double height)
{
base.OnSizeAllocated(width, height);
UpdateLayoutMode(width);
}
/// <summary>
/// Обновляет режим макета в зависимости от ширины экрана
/// На широких экранах: Flyout (вертикальное меню слева)
/// На узких экранах: TabBar (нижняя панель)
/// </summary>
private void UpdateLayoutMode(double? width = null)
{
try
{
// Получаем текущую ширину окна
double currentWidth = width ?? (Application.Current?.Windows.FirstOrDefault()?.Width ?? 0);
if (currentWidth <= 0)
{
// Если ширина не определена, используем DeviceDisplay
currentWidth = DeviceDisplay.MainDisplayInfo.Width / DeviceDisplay.MainDisplayInfo.Density;
}
bool shouldBeDesktop = currentWidth >= WideScreenThreshold;
Trace.WriteLine($"[AppShell] UpdateLayoutMode: width={currentWidth}, threshold={WideScreenThreshold}, shouldBeDesktop={shouldBeDesktop}, currentMode={_isDesktopMode}");
// Проверяем, нужно ли менять режим
if (shouldBeDesktop == _isDesktopMode)
{
return; // Режим не изменился
}
_isDesktopMode = shouldBeDesktop;
if (_isDesktopMode)
{
// Десктопный режим - показываем Flyout, скрываем TabBar
SwitchToDesktopMode();
}
else
{
// Мобильный режим - показываем TabBar, скрываем Flyout
SwitchToMobileMode();
}
}
catch (Exception ex)
{
Trace.WriteLine($"[AppShell] ⚠️ Ошибка UpdateLayoutMode: {ex.Message}");
}
}
private void SwitchToDesktopMode()
{
try
{
Trace.WriteLine("[AppShell] >>> Переключение на десктопный режим (Flyout)");
// Скрываем TabBar
MobileTabBar.IsVisible = false;
// Показываем FlyoutItems
DesktopFlyoutNews.IsVisible = true;
DesktopFlyoutEmployees.IsVisible = true;
DesktopFlyoutDepartments.IsVisible = true;
DesktopFlyoutRequests.IsVisible = true;
DesktopFlyoutProfile.IsVisible = true;
// Включаем Flyout в режим Locked (всегда видим)
FlyoutBehavior = FlyoutBehavior.Locked;
FlyoutIsPresented = true;
// Переходим на первый FlyoutItem
CurrentItem = DesktopFlyoutNews;
Trace.WriteLine("[AppShell] ✅ Десктопный режим активирован");
}
catch (Exception ex)
{
Trace.WriteLine($"[AppShell] ❌ Ошибка SwitchToDesktopMode: {ex.Message}");
}
}
private void SwitchToMobileMode()
{
try
{
Trace.WriteLine("[AppShell] >>> Переключение на мобильный режим (TabBar)");
// Скрываем FlyoutItems
DesktopFlyoutNews.IsVisible = false;
DesktopFlyoutEmployees.IsVisible = false;
DesktopFlyoutDepartments.IsVisible = false;
DesktopFlyoutRequests.IsVisible = false;
DesktopFlyoutProfile.IsVisible = false;
// Отключаем Flyout
FlyoutBehavior = FlyoutBehavior.Disabled;
FlyoutIsPresented = false;
// Показываем TabBar
MobileTabBar.IsVisible = true;
// Переходим на TabBar
CurrentItem = MobileTabBar;
Trace.WriteLine("[AppShell] ✅ Мобильный режим активирован");
}
catch (Exception ex)
{
Trace.WriteLine($"[AppShell] ❌ Ошибка SwitchToMobileMode: {ex.Message}");
}
}
}