<commit_before>﻿using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System.Windows.Input;
using Avalonia.Threading;
using MangaReader.Core.Services;

namespace MangaReader.Avalonia.ViewModel.Command
{
  public abstract class BaseCommand : ICommand, INotifyPropertyChanged
  {
    private string name;
    private string icon;
    private bool isVisible = true;

    public string Name
    {
      get { return name; }
      set
      {
        name = value;
        OnPropertyChanged();
      }
    }

    public string Icon
    {
      get { return icon; }
      set
      {
        icon = value;
        OnPropertyChanged();
      }
    }

    public bool IsVisible
    {
      get { return isVisible; }
      set
      {
        isVisible = value;
        OnPropertyChanged();
      }
    }

    bool ICommand.CanExecute(object parameter)
    {
      var canExecute = this.CanExecute(parameter);
      IsVisible = canExecute;
      return canExecute;
    }

    async void ICommand.Execute(object parameter)
    {
      var commandName = Name ?? GetType().Name;
      Log.Add($"Command '{commandName}' started.");
      await Execute(parameter).ConfigureAwait(true);
    }

    public virtual bool CanExecute(object parameter)
    {
      return true;
    }

    public abstract Task Execute(object parameter);

    public event EventHandler CanExecuteChanged;

    public virtual void OnCanExecuteChanged()
    {
      void InvokeCanExecuteChanged()
      {
        //HACK: if button deattach from logical tree when isvisible = false, button not attach on next show.
        // Not attach -> not subscribe to CanExecuteChanged.
        if (CanExecuteChanged == null && !IsVisible)
          IsVisible = true;

        CanExecuteChanged?.Invoke(this, EventArgs.Empty);
      }

      if (Dispatcher.UIThread.CheckAccess())
        InvokeCanExecuteChanged();
      else
        Dispatcher.UIThread.InvokeAsync(InvokeCanExecuteChanged);
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
  }
}<commit_msg>Try to fix build on appveyor.<commit_after>﻿using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System.Windows.Input;
using Avalonia.Threading;
using MangaReader.Core.Services;

namespace MangaReader.Avalonia.ViewModel.Command
{
  public abstract class BaseCommand : ICommand, INotifyPropertyChanged
  {
    private string name;
    private string icon;
    private bool isVisible = true;

    public string Name
    {
      get { return name; }
      set
      {
        name = value;
        OnPropertyChanged();
      }
    }

    public string Icon
    {
      get { return icon; }
      set
      {
        icon = value;
        OnPropertyChanged();
      }
    }

    public bool IsVisible
    {
      get { return isVisible; }
      set
      {
        isVisible = value;
        OnPropertyChanged();
      }
    }

    bool ICommand.CanExecute(object parameter)
    {
      var canExecute = this.CanExecute(parameter);
      IsVisible = canExecute;
      return canExecute;
    }

    async void ICommand.Execute(object parameter)
    {
      var commandName = Name ?? GetType().Name;
      Log.Add($"Command '{commandName}' started.");
      await Execute(parameter).ConfigureAwait(true);
    }

    public virtual bool CanExecute(object parameter)
    {
      return true;
    }

    public abstract Task Execute(object parameter);

    public event EventHandler CanExecuteChanged;

    public virtual void OnCanExecuteChanged()
    {
      void InvokeCanExecuteChanged()
      {
        //HACK: if button deattach from logical tree when isvisible = false, button not attach on next show.
        // Not attach -> not subscribe to CanExecuteChanged.
        if (CanExecuteChanged == null && !IsVisible)
          IsVisible = true;

        CanExecuteChanged?.Invoke(this, EventArgs.Empty);
      }

      if (Dispatcher.UIThread.CheckAccess())
        InvokeCanExecuteChanged();
      else
        Dispatcher.UIThread.InvokeAsync((Action)InvokeCanExecuteChanged);
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
  }
}
{'fraction_non_alphanumeric': 0.08238636363636363, 'fraction_numerical': 0.0, 'mean_word_length': 2.5841816758026623, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5320590', 'n_tokens_mistral': 1232, 'n_tokens_neox': 1196, 'n_words': 317}