using AvParser.Core.Collecting;
using AvParser.Core.Collecting.Sources;
using AvParser.UI.Localization;
using ReactiveUI;
namespace AvParser.UI.ViewModels;
/// A media source paired with its translated name and description.
///
/// The domain knows nothing about languages, so carries English text.
/// This looks the id up as Source.{id}.Name and falls back to what the source itself says —
/// which is what user-added sources always do, since their name is data the user typed, not a resx
/// key. Disposable because the catalog rebuilds these on every edit, and each one holds a
/// language-changed subscription that would otherwise leak.
///
public sealed class MediaSourceViewModel : ReactiveObject, IDisposable
{
private bool _isSelected;
/// Wraps a source.
public MediaSourceViewModel(IMediaSource source)
{
Source = source ?? throw new ArgumentNullException(nameof(source));
Localizer.Instance.LanguageChanged += OnLanguageChanged;
}
/// Whether the next run includes this source.
///
/// Ticking is what a run acts on; the list's highlight only says which source the editor,
/// the delete button and the purge button are aimed at. Keeping the two apart is what lets a
/// run cover five sources while the user edits a sixth.
///
public bool IsSelected
{
get => _isSelected;
set => this.RaiseAndSetIfChanged(ref _isSelected, value);
}
/// The source itself.
public IMediaSource Source { get; }
/// The config behind the source, when it is a pattern source (they all are today).
public PatternSourceConfig? Config => (Source as PatternMediaSource)?.Config;
/// Stable identifier.
public string Id => Source.Id;
/// Translated name, or the source's own when untranslated.
public string Name => Localizer.Instance.GetOrDefault($"Source.{Id}.Name", Source.DisplayName);
/// Translated description, or the source's own when untranslated.
public string Description => Localizer.Instance.GetOrDefault($"Source.{Id}.Description", Source.Description);
/// Whether this source goes to the network at all.
public bool RequiresNetwork => Source.RequiresNetwork;
///
/// Whether this source may run from the user's own address when no proxy is live.
///
///
/// Anything that is not a configured pattern source answers : the safe
/// end, since a source with nowhere to say otherwise has not said otherwise.
///
public bool AllowsDirectConnection => Config?.AllowDirectConnection ?? false;
/// Whether a run including this source is gated on a live proxy.
public bool NeedsProxy => RequiresNetwork && !AllowsDirectConnection;
///
public override string ToString() => Name;
///
public void Dispose() => Localizer.Instance.LanguageChanged -= OnLanguageChanged;
private void OnLanguageChanged(object? sender, EventArgs e)
{
this.RaisePropertyChanged(nameof(Name));
this.RaisePropertyChanged(nameof(Description));
}
}