Table of Contents

Class MainViewModel

Namespace
McServerLauncher.ViewModels
Assembly
McServerLauncher.dll

Main ViewModel: manages the server list, the selected server and persistence.

public class MainViewModel : ObservableObject, INotifyPropertyChanged, INotifyPropertyChanging
Inheritance
MainViewModel
Implements
Inherited Members

Constructors

MainViewModel(string?)

Default constructor uses %APPDATA%; dataDir is for tests.

public MainViewModel(string? dataDir = null)

Parameters

dataDir string

Remarks

Both files go in the same folder, so one parameter settles both services. A test that opened this view model without it would read the server list of whoever is running the test and write its own back over it.

Properties

AnyServerRunning

True if any server is running (to warn on close).

public bool AnyServerRunning { get; }

Property Value

bool

CheckForUpdatesNowCommand

Gets an IAsyncRelayCommand instance wrapping McServerLauncher.ViewModels.MainViewModel.CheckForUpdatesNow().

[ExcludeFromCodeCoverage]
public IAsyncRelayCommand CheckForUpdatesNowCommand { get; }

Property Value

IAsyncRelayCommand

ConfigureServerCommand

Gets an IRelayCommand instance wrapping McServerLauncher.ViewModels.MainViewModel.ConfigureServer().

[ExcludeFromCodeCoverage]
public IRelayCommand ConfigureServerCommand { get; }

Property Value

IRelayCommand

DismissUpdateCommand

Gets an IRelayCommand instance wrapping McServerLauncher.ViewModels.MainViewModel.DismissUpdate().

[ExcludeFromCodeCoverage]
public IRelayCommand DismissUpdateCommand { get; }

Property Value

IRelayCommand

EditAppearanceCommand

Gets an IRelayCommand instance wrapping McServerLauncher.ViewModels.MainViewModel.EditAppearance().

[ExcludeFromCodeCoverage]
public IRelayCommand EditAppearanceCommand { get; }

Property Value

IRelayCommand

HasNewServerDraft

An unfinished new server is waiting, put away while another server is being looked at.

public bool HasNewServerDraft { get; }

Property Value

bool

HasSelection

public bool HasSelection { get; }

Property Value

bool

IsAboutSection

public bool IsAboutSection { get; }

Property Value

bool

IsCheckingUpdates

public bool IsCheckingUpdates { get; }

Property Value

bool

IsCreatingServer

The new-server panel is on screen.

public bool IsCreatingServer { get; }

Property Value

bool

IsEditingServer

The selected server's settings are on screen.

public bool IsEditingServer { get; }

Property Value

bool

IsNewServerOpen

Whether the new-server panel has the detail area, instead of a server.

[ExcludeFromCodeCoverage]
public bool IsNewServerOpen { get; set; }

Property Value

bool

IsServersSection

public bool IsServersSection { get; }

Property Value

bool

IsSettingsSection

public bool IsSettingsSection { get; }

Property Value

bool

IsTunnelsSection

public bool IsTunnelsSection { get; }

Property Value

bool

IsUpToDate

public bool IsUpToDate { get; }

Property Value

bool

IsUpdating

[ExcludeFromCodeCoverage]
public bool IsUpdating { get; set; }

Property Value

bool

Languages

public IReadOnlyList<MainViewModel.LanguageOption> Languages { get; }

Property Value

IReadOnlyList<MainViewModel.LanguageOption>

LastUpdateCheck

[ExcludeFromCodeCoverage]
public DateTime? LastUpdateCheck { get; set; }

Property Value

DateTime?

NewServerPanel

The new server being made or added, kept while it is unfinished; null otherwise.

[ExcludeFromCodeCoverage]
public NewServerView? NewServerPanel { get; set; }

Property Value

NewServerView

Remarks

Kept even while it is not on screen: opening a server from the list puts the panel away without throwing it out, and "+ Nuevo" brings it back where it was left. A download that had already started goes on meanwhile, and the server joins the list when it ends.

NewServerTip

public string NewServerTip { get; }

Property Value

string

OpenBackupSettingsCommand

Gets an IRelayCommand instance wrapping McServerLauncher.ViewModels.MainViewModel.OpenBackupSettings().

[ExcludeFromCodeCoverage]
public IRelayCommand OpenBackupSettingsCommand { get; }

Property Value

IRelayCommand

OpenLinkCommand

Gets an IRelayCommand<T> instance wrapping OpenLink(string).

[ExcludeFromCodeCoverage]
public IRelayCommand<string?> OpenLinkCommand { get; }

Property Value

IRelayCommand<string>

RemoveServerCommand

[ExcludeFromCodeCoverage]
public IAsyncRelayCommand<ServerViewModel?> RemoveServerCommand { get; }

Property Value

IAsyncRelayCommand<ServerViewModel>

SaveCommand

Gets an IRelayCommand instance wrapping McServerLauncher.ViewModels.MainViewModel.Save().

[ExcludeFromCodeCoverage]
public IRelayCommand SaveCommand { get; }

Property Value

IRelayCommand

Section

[ExcludeFromCodeCoverage]
public AppSection Section { get; set; }

Property Value

AppSection

SelectedLanguage

[ExcludeFromCodeCoverage]
public MainViewModel.LanguageOption? SelectedLanguage { get; set; }

Property Value

MainViewModel.LanguageOption

SelectedServer

[ExcludeFromCodeCoverage]
public ServerViewModel? SelectedServer { get; set; }

Property Value

ServerViewModel

ServerSettingsPanel

The selected server's settings, while they have the detail area; null otherwise.

[ExcludeFromCodeCoverage]
public ServerSettingsView? ServerSettingsPanel { get; set; }

Property Value

ServerSettingsView

Remarks

Kept while another section of the app is looked at, like the new-server panel: going to the tunnels and back finds the page where it was left. It goes when another server is picked, and nothing that would lose an unsaved change is allowed to make it go — see TryLeave().

Servers

public ObservableCollection<ServerViewModel> Servers { get; }

Property Value

ObservableCollection<ServerViewModel>

Settings

The settings screen, which saves as it goes.

public SettingsViewModel Settings { get; }

Property Value

SettingsViewModel

ShowAboutCommand

Gets an IRelayCommand instance wrapping McServerLauncher.ViewModels.MainViewModel.ShowAbout().

[ExcludeFromCodeCoverage]
public IRelayCommand ShowAboutCommand { get; }

Property Value

IRelayCommand

ShowEmptyState

public bool ShowEmptyState { get; }

Property Value

bool

ShowNewServerCommand

Gets an IRelayCommand instance wrapping McServerLauncher.ViewModels.MainViewModel.ShowNewServer().

[ExcludeFromCodeCoverage]
public IRelayCommand ShowNewServerCommand { get; }

Property Value

IRelayCommand

ShowServerDetail

The selected server's detail, unless the new-server panel or its settings have the space.

public bool ShowServerDetail { get; }

Property Value

bool

ShowServersCommand

Gets an IRelayCommand instance wrapping McServerLauncher.ViewModels.MainViewModel.ShowServers().

[ExcludeFromCodeCoverage]
public IRelayCommand ShowServersCommand { get; }

Property Value

IRelayCommand

ShowSettingsCommand

Gets an IRelayCommand instance wrapping McServerLauncher.ViewModels.MainViewModel.ShowSettings().

[ExcludeFromCodeCoverage]
public IRelayCommand ShowSettingsCommand { get; }

Property Value

IRelayCommand

ShowTunnelsCommand

Gets an IRelayCommand instance wrapping McServerLauncher.ViewModels.MainViewModel.ShowTunnels().

[ExcludeFromCodeCoverage]
public IRelayCommand ShowTunnelsCommand { get; }

Property Value

IRelayCommand

TestConnectionCommand

Gets an IRelayCommand instance wrapping McServerLauncher.ViewModels.MainViewModel.TestConnection().

[ExcludeFromCodeCoverage]
public IRelayCommand TestConnectionCommand { get; }

Property Value

IRelayCommand

Tunnels

The tunnels screen: the Playit account, every tunnel on it, and what to do about them.

public TunnelsViewModel Tunnels { get; }

Property Value

TunnelsViewModel

UpdateAvailable

[ExcludeFromCodeCoverage]
public bool UpdateAvailable { get; set; }

Property Value

bool

UpdateCheckFailed

public bool UpdateCheckFailed { get; }

Property Value

bool

UpdateCheckState

What the About screen says about updates; the banner keeps its own flag.

[ExcludeFromCodeCoverage]
public UpdateCheckState UpdateCheckState { get; set; }

Property Value

UpdateCheckState

UpdateCheckText

The line under the version in About: what the last look found, and when.

public string UpdateCheckText { get; }

Property Value

string

UpdateNowCommand

Gets an IAsyncRelayCommand instance wrapping McServerLauncher.ViewModels.MainViewModel.UpdateNow().

[ExcludeFromCodeCoverage]
public IAsyncRelayCommand UpdateNowCommand { get; }

Property Value

IAsyncRelayCommand

UpdateText

[ExcludeFromCodeCoverage]
public string UpdateText { get; set; }

Property Value

string

VersionLineText

"Version 1.12.1 · MIT", under the name in About.

public string VersionLineText { get; }

Property Value

string

VersionText

The version running, as its release calls it.

public string VersionText { get; }

Property Value

string

Methods

Activate()

Starts everything that reaches outside the app: the Playit agent, the update check and its timer, and each server's own watching.

public void Activate()

Remarks

Called from MainWindow once the window is up, not from the constructor. The same split as Activate() and for the same reasons: a constructor goes back to assembling, the app stops downloading an agent and calling GitHub before anything is on screen, and this view model becomes reachable from a test at all.

ShowWhatsNewIfUpdated(Window)

If the current version differs from the last one seen by the user (i.e. it was just updated), shows the what's-new window. Saves the seen version so it isn't repeated.

public void ShowWhatsNewIfUpdated(Window owner)

Parameters

owner Window

ShutdownAllAsync()

Stops all servers IN PARALLEL and saves when the app closes.

public Task ShutdownAllAsync()

Returns

Task

WarnIfServersFileWasCorruptAsync(Window)

If servers.json was corrupt at startup, tells the user what happened — recovered from the ".bak" backup, or started empty with the damaged file kept as ".bad" — instead of silently showing an empty list. Called from MainWindow.Loaded, which in Avalonia can fire again every time the window re-attaches to the visual tree (e.g. restoring from the tray), so the warning is one-shot per session.

public Task WarnIfServersFileWasCorruptAsync(Window owner)

Parameters

owner Window

Returns

Task