- Настройки: выпадающий список «Размер шрифта / текста» (90/100/115/130/150%) - масштаб применяется ко всему главному окну (LayoutTransform), сохраняется и восстанавливается при старте Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
78 lines
3.3 KiB
C#
78 lines
3.3 KiB
C#
using System;
|
||
using System.Collections.ObjectModel;
|
||
using System.Linq;
|
||
using System.Threading.Tasks;
|
||
using Avalonia.Media;
|
||
using CommunityToolkit.Mvvm.ComponentModel;
|
||
using Elfisa.Core;
|
||
|
||
namespace Elfisa.Avalonia.ViewModels;
|
||
|
||
public partial class SettingsViewModel : ViewModelBase
|
||
{
|
||
private readonly ApiClient _api = new();
|
||
|
||
/// <summary>Пункт «По умолчанию» в списке шрифтов.</summary>
|
||
public const string DefaultFontLabel = "По умолчанию";
|
||
|
||
[ObservableProperty] private string _apiBaseUrl = "";
|
||
public string[] Themes { get; } = { "Светлая", "Тёмная" };
|
||
[ObservableProperty] private int _themeIndex;
|
||
|
||
/// <summary>Размер шрифта/текста — масштаб интерфейса.</summary>
|
||
public string[] FontSizes { get; } = { "Мелкий (90%)", "Обычный (100%)", "Крупный (115%)", "Очень крупный (130%)", "Огромный (150%)" };
|
||
private static readonly double[] ScaleValues = { 0.9, 1.0, 1.15, 1.3, 1.5 };
|
||
[ObservableProperty] private int _fontSizeIndex = 1;
|
||
public double SelectedScale => ScaleValues[Math.Clamp(FontSizeIndex, 0, ScaleValues.Length - 1)];
|
||
|
||
/// <summary>Все системные шрифты + «По умолчанию» первым.</summary>
|
||
public ObservableCollection<string> Fonts { get; } = new();
|
||
[ObservableProperty] private string _selectedFont = DefaultFontLabel;
|
||
|
||
public ObservableCollection<BuyerLocationDto> Locations { get; } = new();
|
||
[ObservableProperty] private BuyerLocationDto? _selectedLocation;
|
||
|
||
public SettingsViewModel()
|
||
{
|
||
_api.SetToken(Session.Current.Token);
|
||
ApiBaseUrl = SettingsStore.Current.ApiBaseUrl ?? AppConfig.DefaultApiBaseUrl;
|
||
ThemeIndex = SettingsStore.Current.Theme == "Dark" ? 1 : 0;
|
||
|
||
var scale = SettingsStore.Current.UiScale;
|
||
var best = 1;
|
||
for (int i = 0; i < ScaleValues.Length; i++)
|
||
if (Math.Abs(ScaleValues[i] - scale) < Math.Abs(ScaleValues[best] - scale)) best = i;
|
||
FontSizeIndex = best;
|
||
|
||
Fonts.Add(DefaultFontLabel);
|
||
foreach (var f in FontManager.Current.SystemFonts
|
||
.Select(x => x.Name)
|
||
.Where(n => !string.IsNullOrWhiteSpace(n))
|
||
.Distinct()
|
||
.OrderBy(n => n, StringComparer.CurrentCultureIgnoreCase))
|
||
Fonts.Add(f);
|
||
|
||
var saved = SettingsStore.Current.FontFamily;
|
||
SelectedFont = !string.IsNullOrWhiteSpace(saved) && Fonts.Contains(saved!)
|
||
? saved!
|
||
: DefaultFontLabel;
|
||
|
||
if (Session.Current.IsAuthenticated) _ = LoadLocationsAsync();
|
||
}
|
||
|
||
private async Task LoadLocationsAsync()
|
||
{
|
||
try
|
||
{
|
||
var locs = await _api.GetBuyerLocationsAsync();
|
||
Locations.Clear();
|
||
foreach (var l in locs) Locations.Add(l);
|
||
var savedId = SettingsStore.Current.DefaultLocationId;
|
||
SelectedLocation = Locations.FirstOrDefault(l => l.BuyerLocationId == savedId)
|
||
?? Locations.FirstOrDefault(l => l.IsDefault)
|
||
?? Locations.FirstOrDefault();
|
||
}
|
||
catch { /* локации не критичны для настроек */ }
|
||
}
|
||
}
|