Esempio n. 1
0
        public CreateFileViewModel(ISessionService applicationService, IAlertDialogFactory alertDialogFactory)
        {
            Title = "Create File";

            this.WhenAnyValue(x => x.Name).Subscribe(x => CommitMessage = "Created " + x);

            _canCommit = this.WhenAnyValue(x => x.Name)
                .Select(x => !string.IsNullOrEmpty(x))
                .ToProperty(this, x => x.CanCommit);

            SaveCommand = ReactiveCommand.CreateAsyncTask(
                this.WhenAnyValue(x => x.Name).Select(x => !string.IsNullOrEmpty(x)), 
                async _ =>
            {
                var content = Content ?? string.Empty;

                var path = Path;
                if (string.IsNullOrEmpty(Path))
                    path = "/";
                path = System.IO.Path.Combine(path, Name);
                var request = applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].UpdateContentFile(path, CommitMessage, content, null, Branch);
                await applicationService.Client.ExecuteAsync(request);
                Dismiss();
            });

            DismissCommand = ReactiveCommand.CreateAsyncTask(async t =>
            {
                if (string.IsNullOrEmpty(Name) && string.IsNullOrEmpty(Content)) return true;
                return await alertDialogFactory.PromptYesNo("Discard File?", "Are you sure you want to discard this file?");
            });
            DismissCommand.Where(x => x).Subscribe(_ => Dismiss());
        }
        public AgentAnnotationViewModel(ISharedDataService sharedDataService, MeetingViewModel meeting)
            : base(sharedDataService, meeting)
        {
            _annotations = new ReactiveList<AnnotationViewModel>();

            var annotationsChangedObs = _annotations
                .WhenAnyObservable(p => p.Changed)
                .Select(p => AreThereAnnotationInTheCurrentPage());

            var activeToolObs = Meeting.WhenAnyValue(vm => vm.ActiveTool).Where(t => t != null);
            var pageChangedObs = activeToolObs
                             .Select(t => t.WhenAnyValue(v => v.CurrentPageNumber, p => AreThereAnnotationInTheCurrentPage()))
                             .Switch(); // Only listen to the most recent sequence of property changes (active tool)
            var toolChangedObs = activeToolObs.Select(t => AreThereAnnotationInTheCurrentPage());

            _containsAnnotationsForCurrentPage = toolChangedObs.Merge(pageChangedObs).Merge(annotationsChangedObs)
                .ToProperty(this, p => p.ContainsAnnotationsForCurrentPage); 

            AnnotationTools = new AnnotationToolViewModel(this);

            // when the IsEditing flag changes to false, it means an edit has just completed and we can send
            // the updates annotations to the client
            _isEditingSub = this.WhenAnyValue(p => p.IsEditing)
                .Where(p => !p)
                .Subscribe(_ => UpdateAnnotationModelAnnotations());
        }
Esempio n. 3
0
        public OAuthFlowLoginViewModel(
            IAccountsRepository accountsRepository,
            IActionMenuFactory actionMenuService,
            IAlertDialogFactory alertDialogService)
        {
            _accountsRepository = accountsRepository;
            _alertDialogService = alertDialogService;

            Title = "Login";

            var oauthLogin = ReactiveCommand.Create().WithSubscription(_ =>
                NavigateTo(this.CreateViewModel<OAuthTokenLoginViewModel>()));

            var canLogin = this.WhenAnyValue(x => x.Code).Select(x => !string.IsNullOrEmpty(x));
            var loginCommand = ReactiveCommand.CreateAsyncTask(canLogin,_ => Login(Code));
            loginCommand.Subscribe(x => MessageBus.Current.SendMessage(new LogoutMessage()));
            LoginCommand = loginCommand;

            ShowLoginOptionsCommand = ReactiveCommand.CreateAsyncTask(sender =>
            {
                var actionMenu = actionMenuService.Create();
                actionMenu.AddButton("Login via Token", oauthLogin);
                return actionMenu.Show(sender);
            });

            _loginUrl = this.WhenAnyValue(x => x.WebDomain)
                .IsNotNull()
                .Select(x => x.TrimEnd('/'))
                .Select(x => 
                    string.Format(x + "/login/oauth/authorize?client_id={0}&redirect_uri={1}&scope={2}", 
                    ClientId, Uri.EscapeDataString(RedirectUri), Uri.EscapeDataString(string.Join(",", OctokitClientFactory.Scopes))))
                .ToProperty(this, x => x.LoginUrl);

            WebDomain = DefaultWebDomain;
        }
Esempio n. 4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PlaylistViewModel" /> class.
        /// </summary>
        /// <param name="playlist">The playlist info.</param>
        /// <param name="renameRequest">
        /// A function that requests the rename of the playlist. Return true, if the rename is
        /// granted, otherwise false.
        /// </param>
        public PlaylistViewModel(Playlist playlist, Func<string, bool> renameRequest)
        {
            this.playlist = playlist;
            this.renameRequest = renameRequest;

            this.disposable = new CompositeDisposable();

            this.entries = playlist
                .CreateDerivedCollection(entry => new PlaylistEntryViewModel(entry))
                .DisposeWith(this.disposable);
            this.entries.ItemsRemoved.Subscribe(x => x.Dispose());

            this.playlist.WhenAnyValue(x => x.CurrentSongIndex).ToUnit()
                .Merge(this.entries.Changed.ToUnit())
                .Subscribe(_ => this.UpdateCurrentSong())
                .DisposeWith(this.disposable);

            IObservable<List<PlaylistEntryViewModel>> remainingSongs = this.entries.Changed
                .Select(x => Unit.Default)
                .Merge(this.playlist.WhenAnyValue(x => x.CurrentSongIndex).ToUnit())
                .Select(x => this.entries.Reverse().TakeWhile(entry => !entry.IsPlaying).ToList());

            this.songsRemaining = remainingSongs
                .Select(x => x.Count)
                .ToProperty(this, x => x.SongsRemaining)
                .DisposeWith(this.disposable);

            this.timeRemaining = remainingSongs
                .Select(x => x.Any() ? x.Select(entry => entry.Duration).Aggregate((t1, t2) => t1 + t2) : (TimeSpan?)null)
                .ToProperty(this, x => x.TimeRemaining)
                .DisposeWith(this.disposable);

            this.CurrentPlayingEntry = this.Model.WhenAnyValue(x => x.CurrentSongIndex).Select(x => x == null ? null : this.entries[x.Value]);
        }
        public InsertGistViewModel()
        {
            //var client = new GitHubClient() { Username = "******", Password = "******" };

            var privateImage = new BitmapImage(new Uri(@"pack://*****:*****@"pack://application:,,,/data/public.png"));

            _PublicPrivateIcon = this.WhenAny(x => x.IsPrivateGist, x => x.Value)
                .Select(x => x ? privateImage : publicImage)
                .ToProperty(this, x => x.PublicPrivateIcon);

            CreateGist = new ReactiveAsyncCommand();

            CreateGist.RegisterAsyncObservable(_ => client.CreateGist(SelectionText, !IsPrivateGist))
                .Select(x => x.html_url)
                .BindTo(this, x => x.LastGistUrl);

            CopyToClipboard = new ReactiveCommand(
                this.WhenAny(x => x.LastGistUrl, x => !String.IsNullOrWhiteSpace(x.Value)));

            CopyToClipboard.Subscribe(_ => Clipboard.SetText(LastGistUrl));

            this.WhenAny(x => x.SelectionText, x => x.Value)
                .Where(_ => LastGistUrl != null)
                .Subscribe(_ => LastGistUrl = null);
        }
        public void OAPHShouldRethrowErrors()
        {
            var input = new Subject<int>();
            var sched = new TestScheduler();

            var fixture = new ObservableAsPropertyHelper<int>(input,
                _ => { }, -5, sched);

            Assert.AreEqual(-5, fixture.Value);
            (new[] { 1, 2, 3, 4 }).Run(x => input.OnNext(x));

            sched.Run();

            Assert.AreEqual(4, fixture.Value);

            input.OnError(new Exception("Die!"));

            sched.Run();

            try {
                Assert.AreEqual(4, fixture.Value);
            } catch {
                return;
            }
            Assert.Fail("We should've threw there");
        }
Esempio n. 7
0
        public Threshold(IObservable<int> thresholdState)
        {
            //this.WhenAny(vm => vm.Good, vm => vm.Bad, vm => vm.OK, (g, b, o) =>
            //{

            //});

            this.Good = new Range();
            this.Bad = new Range();
            this.OK = new Range();

            var obs = thresholdState.Select(value =>
               {
                   if (value.Between(this.Good.Min, this.Good.Max))
                       return "Good";

                   if (value.Between(this.OK.Min, this.ok.Max))
                       return "OK";

                   if (value.Between(this.Bad.Min, this.bad.Max))
                       return "Bad";

                   return "";
               });

            this.state = obs.ToProperty(this, vm => vm.State);
            obs.Subscribe(_ =>
            {
                Trace.WriteLine(_);
            });
        }
Esempio n. 8
0
 public TreePageViewModel(TreeNode[] nodes)
 {
     Nodes = nodes;
     _details = this.WhenAnyValue(x => x.SelectedNode)
         .Select(x => x != null ? new ControlDetailsViewModel(x.Control) : null)
         .ToProperty(this, x => x.Details);
 }
Esempio n. 9
0
        public MainViewModel()
        {
            _multiEngine = this.ObservableToProperty(
                Engines.Changed.Select(_ => Engines.Count > 1),
                vm => vm.MultiEngine);
            _singleEngine = this.ObservableToProperty(
                Engines.Changed.Select(_ => Engines.Count == 1),
                vm => vm.SingleEngine);
            _languages = this.ObservableToProperty(
                this.ObservableForProperty(vm => vm.SelectedEngine)
                    .Select(_ => SelectedEngine.Value.Languages),
                vm => vm.Languages);
            _languages.Subscribe(_ => EnsureLanguage());
            Engines.Changed.Subscribe(_ => EnsureEngine());

            Observable.Merge(
                this.ObservableForProperty(vm => vm.DesignTimeMode).IgnoreValues(),
                this.ObservableForProperty(vm => vm.SelectedEngine).IgnoreValues(),
                this.ObservableForProperty(vm => vm.SelectedLanguage).IgnoreValues(),
                this.ObservableForProperty(vm => vm.RazorCode).IgnoreValues())
                .ObserveOn(RxApp.DeferredScheduler)
                .Subscribe(_ => Regenerate());

            this.PropertyChanged += MainViewModel_PropertyChanged;
        }
Esempio n. 10
0
        public SettingsViewModel(
            IScreen screen,
            ISettingsProvider settingsProvider,
            IFolderHelper folderHelper, 
            IAppContext appContext)
        {
            HostScreen = screen;

            BackCommand = new ReactiveAsyncCommand();
            BackCommand.RegisterAsyncAction(_ => HostScreen.Router.NavigateBack.Execute(null));

            SelectFolder = new ReactiveAsyncCommand();
            SelectFolder.RegisterAsyncAction(_ =>
            {
                var result = folderHelper.SelectFolder();
                if (result.Result == true) {
                    UpdateLocation = result.Folder;
                }
            }, appContext.DispatcherScheduler);

            UpdateLocation = settingsProvider.UpdateLocation;

            _IsError = this.WhenAny(vm => vm.UpdateLocation, vm => vm.Value)
                           .DistinctUntilChanged()
                           .Throttle(TimeSpan.FromMilliseconds(500))
                           .ObserveOn(appContext.DispatcherScheduler)
                           .Select(text => !IsUrlOrFolder(text))
                           .Do(error => {
                                if (!error) {
                                    settingsProvider.UpdateLocation = UpdateLocation;
                                }
                            })
                            .ToProperty(this, vm => vm.IsError, setViaReflection: false);
        }
Esempio n. 11
0
        public MyIssuesViewModel(ISessionService sessionService)
            : base(sessionService)
        {
            _sessionService = sessionService;

            Title = "My Issues";
            Filter = MyIssuesFilterModel.CreateOpenFilter();

            _selectedFilter = this.WhenAnyValue(x => x.Filter)
                .Select(x =>
                {
                    if (x == null || _openFilter.Equals(x))
                        return 0;
                    return _closedFilter.Equals(x) ? 1 : -1;
                })
                .ToProperty(this, x => x.SelectedFilter);

            this.WhenAnyValue(x => x.Filter).Skip(1).Subscribe(filter => {
                InternalItems.Clear();
                LoadCommand.ExecuteIfCan();
                CustomFilterEnabled = !(filter == _closedFilter || filter == _openFilter);
            });

            GoToFilterCommand = ReactiveCommand.Create();
            GoToFilterCommand.Subscribe(_ => {
                var vm = this.CreateViewModel<MyIssuesFilterViewModel>();
                vm.Init(Filter);
                vm.SaveCommand.Subscribe(filter => Filter = filter);
                NavigateTo(vm);
            });
        }
Esempio n. 12
0
        public IndexViewModel(IRepository repo)
        {
            this.repo = repo;
            this.refreshCommand = ReactiveCommand.Create();

            this.repositoryStatus = this.refreshCommand.Select(u =>
            {
                return repo.RetrieveStatus(new StatusOptions() { Show = StatusShowOption.IndexAndWorkDir });
            }).ToProperty(this, vm => vm.RepositoryStatus);

            this.statusEntries = this
                .WhenAny(vm => vm.RepositoryStatus, change =>
                {
                    var status = change.GetValue();

                    return status.CreateDerivedCollection(s => s, null, null, null, this.refreshCommand);
                }).ToProperty(this, vm => vm.StatusEntries);

            var resetSignal = this.WhenAny(vm => vm.StatusEntries, change =>
             {
                 return 0;
             });

            var allEntries = this.WhenAny(vm => vm.StatusEntries, change => change.GetValue());

            this.unstagedEntries = allEntries.Select(s =>
            {
                return s.CreateDerivedCollection(i => i, i => Unstaged(i.State), null, resetSignal);
            }).ToProperty(this, vm => vm.UnstagedEntries);

            this.stagedEntries = allEntries.Select(s =>
            {
                return s.CreateDerivedCollection(i => i, i => Staged(i.State), null, resetSignal);
            }).ToProperty(this, vm => vm.StagedEntries);
        }
 public ClientAnnotationViewModel(ISharedDataService sharedDataService, MeetingViewModel meeting) : base(sharedDataService, meeting)
 {
     // create the client annotations property, a mapped version of the agent's properties based on the screen sizes.
     _annotationsChangedSub = _clientAnnotations = AnnotationsModel
                                                       .WhenAnyValue(v => v.Annotations, v => v.Select(p => CreateAnnotationViewModel(p)))
                                                       .ToProperty(this, v => v.Annotations);
 }
Esempio n. 14
0
 public VisualTreeViewModel(Control root)
 {
     Nodes = VisualTreeNode.Create(root);
     _details = this.WhenAnyValue(x => x.SelectedNode)
         .Select(x => x != null ? new ControlDetailsViewModel(x.Control) : null)
         .ToProperty(this, x => x.Details);
 }
 public CountryViewModel(string name, float population, Task<IBitmap> countryFlag, double longitude, double latitude)
     : base(name, population, longitude, latitude)
 {
     this.countryFlag = countryFlag
         .ToObservable()
         .ToProperty(this, x => x.CountryFlag);
 }
Esempio n. 16
0
        public GistCreationViewModel(
            IRepositoryHost repositoryHost,
            ISelectedTextProvider selectedTextProvider,
            IGistPublishService gistPublishService,
            IUsageTracker usageTracker)
        {
            Title = Resources.CreateGistTitle;
            apiClient = repositoryHost.ApiClient;
            this.gistPublishService = gistPublishService;
            this.usageTracker = usageTracker;

            FileName = VisualStudio.Services.GetFileNameFromActiveDocument() ?? Resources.DefaultGistFileName;
            SelectedText = selectedTextProvider.GetSelectedText();

            // This class is only instantiated after we are logged into to a github account, so we should be safe to grab the first one here as the defaut.
            account = repositoryHost.ModelService.GetAccounts()
                .FirstAsync()
                .Select(a => a.First())
                .ObserveOn(RxApp.MainThreadScheduler)
                .ToProperty(this, vm => vm.Account);

            var canCreateGist = this.WhenAny( 
                x => x.FileName,
                fileName => !String.IsNullOrEmpty(fileName.Value));

            CreateGist = ReactiveCommand.CreateAsyncObservable(canCreateGist, OnCreateGist);
        }
 public LoginRouteViewModel(IScreen hostScreen)
 {
     HostScreen = hostScreen;
     var authentication = new Authentication();
     var canLogin = this.WhenAny(x => x.LoginName,
         x => x.Password,
         (l, p) => !String.IsNullOrWhiteSpace(l.Value) && !String.IsNullOrWhiteSpace(p.Value));
     LoginCommand = new ReactiveCommand(canLogin);
     var loggedIn = LoginCommand.RegisterAsync(_ => Observable.Start(() =>
     {
         var authenticationResult = authentication.AuthenticateAsync(LoginName,
             Password).
                                                   Result;
         return authenticationResult == AuthenticationResult.Authenticated
             ? "Přihlášen"
             : "Nepřihlášen";
     }));
     loggedIn.Subscribe(s =>
     {
         if (s == "Přihlášen")
             HostScreen.Router.Navigate.Execute(new PersonListViewModel(HostScreen));
     });
     message = new ObservableAsPropertyHelper<string>(loggedIn,
         s => raisePropertyChanged("Message"));
 }
 public SoundCloudSongViewModel(SoundCloudSong model)
     : base(model)
 {
     this.hasThumbnail = this.WhenAnyValue(x => x.Thumbnail)
         .Select(x => x != null)
         .ToProperty(this, x => x.HasThumbnail);
 }
Esempio n. 19
0
        public MainWindowViewModel()
        {
            var whenAnyColorChanges = this.WhenAny(x => x.Red, x => x.Green, x => x.Blue,
                    (r, g, b) => Tuple.Create(r.Value, g.Value, b.Value))
                .Select(intsToColor);

            _FinalColor = whenAnyColorChanges
                .Where(x => x != null)
                .Select(x => x.Value)
                .ToProperty(this, x => x.FinalColor);

            Ok = ReactiveCommand.Create(whenAnyColorChanges.Select(x => x != null));

            _Images = this.WhenAny(x => x.FinalColor, x => x.Value)
                .Throttle(TimeSpan.FromSeconds(0.7), RxApp.MainThreadScheduler)
                .Do(_ => IsBusy = true)
                .Select(x => imagesForColor(x))
                .Switch()
                .SelectMany(imageListToImages)
                .ObserveOn(RxApp.MainThreadScheduler)
                .Do(_ => IsBusy = false)
                .ToProperty(this, x => x.Images);

            _Images.ThrownExceptions.Subscribe(ex => this.Log().WarnException("Can't load images", ex));
        }
        public YoutubeSongViewModel(YoutubeSong wrapped, Func<string> downloadPathFunc)
            : base(wrapped)
        {
            this.hasThumbnail = this.WhenAnyValue(x => x.Thumbnail)
                .Select(x => x != null)
                .ToProperty(this, x => x.HasThumbnail);

            // Wait for the opening of the context menu to download the YouTube information
            this.WhenAnyValue(x => x.IsContextMenuOpen)
                .FirstAsync(x => x)
                .SelectMany(_ => this.LoadContextMenu().ToObservable())
                .Subscribe();

            // We have to set a dummy here, so that we can connect the commands
            this.isDownloading = Observable.Never<bool>().ToProperty(this, x => x.IsDownloading);

            this.DownloadVideoCommand = ReactiveCommand.CreateAsyncTask(this.WhenAnyValue(x => x.IsDownloading).Select(x => !x),
                x => this.DownloadVideo((VideoInfo)x, downloadPathFunc()));

            this.DownloadAudioCommand = ReactiveCommand.CreateAsyncTask(this.WhenAnyValue(x => x.IsDownloading).Select(x => !x),
                x => this.DownloadAudio((VideoInfo)x, downloadPathFunc()));

            this.isDownloading = this.DownloadVideoCommand.IsExecuting
                .CombineLatest(this.DownloadAudioCommand.IsExecuting, (x1, x2) => x1 || x2)
                .ToProperty(this, x => x.IsDownloading);
        }
Esempio n. 21
0
        public DevToolsViewModel(IControl root)
        {
            _logicalTree = new TreePageViewModel(LogicalTreeNode.Create(root));
            _visualTree = new TreePageViewModel(VisualTreeNode.Create(root));

            this.WhenAnyValue(x => x.SelectedTab).Subscribe(index =>
            {
                switch (index)
                {
                    case 0:
                        Content = _logicalTree;
                        break;
                    case 1:
                        Content = _visualTree;
                        break;
                }
            });

            _focusedControl = KeyboardDevice.Instance
                .WhenAnyValue(x => x.FocusedElement)
                .Select(x => x?.GetType().Name)
                .ToProperty(this, x => x.FocusedControl);

            _pointerOverElement = root.GetObservable(TopLevel.PointerOverElementProperty)
                .Select(x => x?.GetType().Name)
                .ToProperty(this, x => x.PointerOverElement);
        }
        public MiniMainWindowViewModel(ITrayMainWindowViewModel trayMainWindowViewModel) {
            TrayViewModel = trayMainWindowViewModel;
            _taskbarToolTip = this.WhenAnyValue(x => x.DisplayName, x => x.TrayViewModel.Status,
                trayMainWindowViewModel.FormatTaskbarToolTip)
                .ToProperty(this, x => x.TaskbarToolTip);
            OpenPopup = ReactiveCommand.Create();
            ShowNotification = ReactiveCommand.CreateAsyncTask(async x => (ITrayNotificationViewModel) x);
            Deactivate = ReactiveCommand.Create().DefaultSetup("Deactivate");
            Deactivate.Subscribe(x => {
                if (TrayViewModel.MainArea is IWelcomeViewModel)
                    return;
                Close.Execute(null);
            });

            OpenPopup
                .Take(1)
                .Delay(TimeSpan.FromSeconds(20))
                .ObserveOnMainThread()
                .Subscribe(x => TrayViewModel.RemoveUpdatedState());

            // TODO: Make this a setting?
            /*            Listen<ApiUserActionStarted>()
                .ObserveOnMainThread()
                .InvokeCommand(OpenPopup);*/
            Listen<AppStateUpdated>()
                .Where(x => x.UpdateState == AppUpdateState.Updating)
                .ObserveOnMainThread()
                .InvokeCommand(OpenPopup);
            Listen<ShowTrayNotification>()
                .Select(x => new TrayNotificationViewModel(x.Subject, x.Text, x.CloseIn, x.Actions))
                .ObserveOnMainThread()
                .InvokeCommand(ShowNotification);
        }
        public TrayMainWindowViewModel(IViewModel mainArea, TrayMainWindowMenu menu, IStatusViewModel status,
            LoginInfo loginInfo, IWelcomeViewModel welcomeViewModel) {
            _mainArea = Consts.FirstRun /* || Cheat.Consts.IsTestVersion */ ? welcomeViewModel : mainArea;
            _menu = menu;
            _status = status;
            _loginInfo = loginInfo;

            welcomeViewModel.Close.Subscribe(x => MainArea = mainArea);

            _taskbarToolTip = this.WhenAnyValue(x => x.DisplayName, x => x.Status, FormatTaskbarToolTip)
                .ToProperty(this, x => x.TitleToolTip);

            _avatarUrl = this.WhenAnyValue<TrayMainWindowViewModel, Uri, AccountInfo>(x => x.LoginInfo.Account,
                x => new Uri("http:" + AvatarCalc.GetAvatarURL(x)))
                .ToProperty(this, x => x.AvatarUrl);

            _installUpdate =
                ReactiveCommand.CreateAsyncTask(
                    this.WhenAnyValue(x => x.UpdateState, state => state == AppUpdateState.UpdateAvailable),
                    async x => await RequestAsync(new OpenWebLink(ViewType.Update)).ConfigureAwait(false))
                    .DefaultSetup("InstallUpdate");
            _goAccount =
                ReactiveCommand.CreateAsyncTask(
                    async x => await RequestAsync(new OpenWebLink(ViewType.Profile)).ConfigureAwait(false))
                    .DefaultSetup("OpenProfile");
            _goPremium =
                ReactiveCommand.CreateAsyncTask(
                    async x =>
                        await
                            RequestAsync(
                                new OpenWebLink(_loginInfo.IsPremium ? ViewType.PremiumAccount : ViewType.GoPremium))
                                .ConfigureAwait(false))
                    .DefaultSetup("GoPremium");

            IViewModel previousMain = null;

            _switchQueue = ReactiveCommand.CreateAsyncTask(
                async x => {
                    if (previousMain == null) {
                        previousMain = _mainArea;
                        MainArea = await RequestAsync(new GetQueue()).ConfigureAwait(false);
                    } else {
                        MainArea = previousMain;
                        previousMain = null;
                    }
                });
            status.SwitchQueue = _switchQueue; // TODO..

            Listen<LoginChanged>()
                .Select(x => x.LoginInfo)
                .ObserveOnMainThread()
                .BindTo(this, x => x.LoginInfo);
            // We need to receive these right away..
            // toDO: Think about how to make this only on WhenActivated
            Listen<AppStateUpdated>()
                .Select(x => x.UpdateState)
                .ObserveOnMainThread()
                .BindTo(this, x => x.UpdateState);
        }
Esempio n. 24
0
        public DownloadVM(
            IDiversityServiceClient Service,
            IConnectivityService Connectivity,
            IFieldDataService Storage,
            IKeyMappingService Mappings,
            EventHierarchyLoader HierarchyLoader,
            [Dispatcher] IScheduler Dispatcher
            ) {
            this.Service = Service;
            this.Connectivity = Connectivity;
            this.Storage = Storage;
            this.Mappings = Mappings;
            this.HierarchyLoader = HierarchyLoader;

            QueryResult = new ReactiveCollection<Event>();

            _IsOnlineAvailable = Connectivity.Status().Select(s => s == ConnectionStatus.Wifi).Do(_ => { this.GetType(); }, ex => { }, () => { })
                .ToProperty(this, x => x.IsOnlineAvailable);

            SearchEvents = new ReactiveAsyncCommand(this.WhenAny(x => x.IsOnlineAvailable, x => x.Value));
            SearchEvents.ShowInFlightNotification(Notifications, DiversityResources.Download_SearchingEvents);
            SearchEvents.ThrownExceptions
                    .ShowServiceErrorNotifications(Notifications)
                    .ShowErrorNotifications(Notifications)
                    .Subscribe();
            SearchEvents
                .RegisterAsyncObservable(query =>
                    Service.GetEventsByLocality(query as string ?? string.Empty)
                    .TakeUntil(this.OnDeactivation())
                )
                .Do(_ => QueryResult.Clear())
                .Subscribe(QueryResult.AddRange);

            CancelDownload = new ReactiveCommand();

            DownloadElement = new ReactiveAsyncCommand(this.WhenAny(x => x.IsOnlineAvailable, x => x.Value));
            DownloadElement.ThrownExceptions
                .ShowServiceErrorNotifications(Notifications)
                .ShowErrorNotifications(Notifications)
                .Subscribe();
            DownloadElement
                .RegisterAsyncObservable(ev => IfNotDownloadedYet(ev as Event)
                    .Select(HierarchyLoader.downloadAndStoreDependencies)
                    .SelectMany(dl => dl.TakeUntil(CancelDownload))
                    .Scan(0, (acc, _) => ++acc)
                    .Do(_ElementsDownloadedSubject.OnNext)
                    );

            _IsDownloading = DownloadElement.ItemsInflight
                .Select(x => x > 0)
                .ToProperty(this, x => x.IsDownloading);

            this.OnDeactivation()
                .Subscribe(_ => Messenger.SendMessage(EventMessage.Default, MessageContracts.INIT));

            _ElementsDownloadedSubject = new Subject<int>();
            _ElementsDownloaded = _ElementsDownloadedSubject.ToProperty(this, x => x.ElementsDownloaded, 0, Dispatcher);
        }
Esempio n. 25
0
 public SettingsViewModel(IEnumerable<ISettingsTabViewModel> settingsTabs) {
     var settings = settingsTabs.OrderBy(GetOrder).ToArray();
     Settings = new SelectionCollectionHelper<ISettingsTabViewModel>(settings) {
         SelectedItem = settings.FirstOrDefault()
     };
     _valid = settings.Select(x => x.WhenAnyValue(s => s.IsValid))
         .CombineLatest(x => x.All(b => b))
         .ToProperty(this, x => x.Valid);
 }
Esempio n. 26
0
        public ViewModelViewHost()
        {
            this.currentView = new SerialDisposable();
            this.viewContract = this
                .WhenAnyObservable(x => x.ViewContractObservable)
                .ToProperty(this, x => x.ViewContract, scheduler: RxApp.MainThreadScheduler);

            this.Initialize();
        }
Esempio n. 27
0
 public CachingStateVm(CachingState cachingState)
 {
     _cachingState = cachingState;
     var progress = cachingState.Progress;
     _finalSize = progress.Select(x => x.Total).ToProperty(this, x => x.FinalSize);
     _cachedSize = progress.Select(x => x.Current).ToProperty(this, x => x.CachedSize);
     _isFullyCached = progress.Select(x => x.Current != 0UL && x.Current == x.Total).ToProperty(this, x => x.IsFullyCached, false);
     _isInitialized = this.WhenAny(x => x.FinalSize, ch => ch.Value > 0).ToProperty(this, x => x.IsInitialized, false);
 }
        public DispatchViewModel(IScreen screen, ISession session)
        {
            HostScreen = screen;
            GoBack = HostScreen.Router.NavigateBack;

            Techs = new ReactiveList<Employee>();
            Tickets = new ReactiveList<Ticket>();

            var getFreshTechs = new ReactiveCommand();
            getFreshTechs.ObserveOn(RxApp.MainThreadScheduler).Subscribe(_ =>
                {
                    Techs.Clear();
                    session.FetchResults<Employee>()
                        .ObserveOn(RxApp.MainThreadScheduler)
                        .Subscribe(x => Techs.Add(x));
                });

            var getFreshTickets = new ReactiveCommand();
            getFreshTickets.ObserveOn(RxApp.MainThreadScheduler).Subscribe(_ =>
                {
                    Tickets.Clear();
                    session.FetchResults<Ticket>()
                        .ObserveOn(RxApp.MainThreadScheduler)
                        .Subscribe(x => Tickets.Add(x));
                });

            Refresh = new ReactiveCommand(session.IsWorking.Select(x => !x));
            Refresh.Subscribe(_ =>
                {
                    getFreshTechs.Execute(default(object));
                    getFreshTickets.Execute(default(object));
                });

            Assign = new ReactiveCommand(Observable.CombineLatest(
                this.WhenAny(
                    x => x.SelectedEmployee,
                    y => y.SelectedTicket,
                    (x, y) => x.Value != null && y.Value != null),
                Refresh.CanExecuteObservable,
                (x, y) => x && y));
            Assign.Subscribe(_ =>
            {
                using (session.ScopedChanges())
                {
                    var eventTaker = session.Take<TicketEvent>();
                    eventTaker.Add(new TicketEvent { Employee = SelectedEmployee, Ticket = SelectedTicket, TicketStatus = TicketStatus.Assigned, Time = DateTime.Now });
                }
            });

            _error = session.ThrownExceptions
                .Select(x => x.Message)
                .ObserveOn(RxApp.MainThreadScheduler)
                .ToProperty(this, x => x.Error);

            Refresh.Execute(default(object));
        }
        public MainWindowViewModel(ILeapMotionService leapMotionService)
        {
            this.leapMotionService = leapMotionService;

            this._fingersDetected = leapMotionService.FingersDetected.ToProperty(this, x => x.FingersDetected);
            this.Disposables.Add(this._fingersDetected);

            this._velocity = leapMotionService.SmoothedVelocity.ToProperty(this, x => x.Velocity);
            this.Disposables.Add(this._velocity);
        }
        protected override void OnInitialize() {
            base.OnInitialize();

            _selectedItem = _mvm.Value.LibraryVM.WhenAnyValue(x => x.SelectedItem.SelectedItem)
                .OfType<IMod>()
                .ToProperty(this, x => x.SelectedItem);

            _isInCollection = this.WhenAny(x => x.SelectedItem, x => x.Value is ToggleableModProxy)
                .ToProperty(this, x => x.IsInCollection);
        }
Esempio n. 31
0
        public MainViewModel(
            ProviderViewModelFactory providerFactory,
            AuthViewModelFactory authFactory,
            IProviderStorage storage,
            IScheduler current,
            IScheduler main)
        {
            _storage = storage;
            _refresh = ReactiveCommand.CreateFromTask(
                storage.Refresh,
                outputScheduler: main);

            var providers = storage.Read();

            providers.Transform(x => providerFactory(x, authFactory(x)))
            .Sort(SortExpressionComparer <IProviderViewModel> .Descending(x => x.Created))
            .ObserveOn(RxApp.MainThreadScheduler)
            .StartWithEmpty()
            .Bind(out _providers)
            .Subscribe();

            _isLoading = _refresh
                         .IsExecuting
                         .ToProperty(this, x => x.IsLoading, scheduler: current);

            _isReady = _refresh
                       .IsExecuting
                       .Skip(1)
                       .Select(executing => !executing)
                       .ToProperty(this, x => x.IsReady, scheduler: current);

            providers.Where(changes => changes.Any())
            .ObserveOn(RxApp.MainThreadScheduler)
            .OnItemAdded(x => SelectedProvider   = Providers.FirstOrDefault())
            .OnItemRemoved(x => SelectedProvider = null)
            .Subscribe();

            var canRemove = this
                            .WhenAnyValue(x => x.SelectedProvider)
                            .Select(provider => provider != null);

            _remove = ReactiveCommand.CreateFromTask(
                () => storage.Remove(SelectedProvider.Id),
                canRemove);

            var canAddProvider = this
                                 .WhenAnyValue(x => x.SelectedSupportedType)
                                 .Select(type => !string.IsNullOrWhiteSpace(type));

            _add = ReactiveCommand.CreateFromTask(
                () => storage.Add(SelectedSupportedType),
                canAddProvider);

            _welcomeScreenVisible = this
                                    .WhenAnyValue(x => x.SelectedProvider)
                                    .Select(provider => provider == null)
                                    .ToProperty(this, x => x.WelcomeScreenVisible);

            _welcomeScreenCollapsed = this
                                      .WhenAnyValue(x => x.WelcomeScreenVisible)
                                      .Select(visible => !visible)
                                      .ToProperty(this, x => x.WelcomeScreenCollapsed);

            var canUnSelect = this
                              .WhenAnyValue(x => x.SelectedProvider)
                              .Select(provider => provider != null);

            _unselect = ReactiveCommand.Create(
                () => { SelectedProvider = null; },
                canUnSelect);

            Activator = new ViewModelActivator();
            this.WhenActivated(disposables =>
            {
                SelectedSupportedType = SupportedTypes.FirstOrDefault();
                _refresh.Execute()
                .Subscribe()
                .DisposeWith(disposables);
            });
        }
Esempio n. 32
0
        public VortexCompilerVM(CompilerVM parent)
        {
            Parent       = parent;
            GameLocation = new FilePickerVM()
            {
                ExistCheckOption = FilePickerVM.CheckOptions.On,
                PathType         = FilePickerVM.PathTypeOptions.Folder,
                PromptTitle      = "Select Game Folder Location"
            };
            DownloadsLocation = new FilePickerVM()
            {
                ExistCheckOption = FilePickerVM.CheckOptions.On,
                PathType         = FilePickerVM.PathTypeOptions.Folder,
                PromptTitle      = "Select Downloads Folder"
            };
            StagingLocation = new FilePickerVM()
            {
                ExistCheckOption = FilePickerVM.CheckOptions.On,
                PathType         = FilePickerVM.PathTypeOptions.Folder,
                PromptTitle      = "Select Staging Folder"
            };

            // Load custom ModList settings when game type changes
            _modListSettings = (this).WhenAny(x => x.SelectedGame)
                               .Select(game =>
            {
                if (game == null)
                {
                    return(null);
                }
                var gameSettings = _settings.ModlistSettings.TryCreate(game.Game);
                return(new ModlistSettingsEditorVM(gameSettings.ModlistSettings));
            })
                               // Interject and save old while loading new
                               .Pairwise()
                               .Do(pair =>
            {
                var(previous, current) = pair;
                previous?.Save();
                current?.Init();
            })
                               .Select(x => x.Current)
                               // Save to property
                               .ObserveOnGuiThread()
                               .ToProperty(this, nameof(ModlistSettings));

            CanCompile = Observable.CombineLatest(
                this.WhenAny(x => x.GameLocation.InError),
                this.WhenAny(x => x.DownloadsLocation.InError),
                this.WhenAny(x => x.StagingLocation.InError),
                this.WhenAny(x => x.ModlistSettings)
                .Select(x => x?.InError ?? Observable.Return(false))
                .Switch(),
                (g, d, s, ml) => !g && !d && !s && !ml)
                         .Publish()
                         .RefCount();

            // Load settings
            _settings    = parent.MWVM.Settings.Compiler.VortexCompilation;
            SelectedGame = _gameOptions.FirstOrDefault(x => x.Game == _settings.LastCompiledGame) ?? _gameOptions[0];
            parent.MWVM.Settings.SaveSignal
            .Subscribe(_ => Unload())
            .DisposeWith(CompositeDisposable);

            // Load custom game settings when game type changes
            (this).WhenAny(x => x.SelectedGame)
            .Select(game => _settings.ModlistSettings.TryCreate(game.Game))
            .Pairwise()
            .Subscribe(pair =>
            {
                // Save old
                var(previous, current) = pair;
                if (previous != null)
                {
                    previous.GameLocation = GameLocation.TargetPath;
                }

                // Load new
                GameLocation.TargetPath = current?.GameLocation;
                if (string.IsNullOrWhiteSpace(GameLocation.TargetPath))
                {
                    SetGameToSteamLocation();
                }
                if (string.IsNullOrWhiteSpace(GameLocation.TargetPath))
                {
                    SetGameToGogLocation();
                }
                DownloadsLocation.TargetPath = current?.DownloadLocation;
                if (string.IsNullOrWhiteSpace(DownloadsLocation.TargetPath))
                {
                    DownloadsLocation.TargetPath = VortexCompiler.RetrieveDownloadLocation(SelectedGame.Game);
                }
                StagingLocation.TargetPath = current?.StagingLocation;
                if (string.IsNullOrWhiteSpace(StagingLocation.TargetPath))
                {
                    StagingLocation.TargetPath = VortexCompiler.RetrieveStagingLocation(SelectedGame.Game);
                }
            })
            .DisposeWith(CompositeDisposable);

            // Find game commands
            FindGameInSteamCommand = ReactiveCommand.Create(SetGameToSteamLocation);
            FindGameInGogCommand   = ReactiveCommand.Create(SetGameToGogLocation);

            // Add additional criteria to download/staging folders
            DownloadsLocation.AdditionalError = this.WhenAny(x => x.DownloadsLocation.TargetPath)
                                                .Select(path => path == null ? ErrorResponse.Success : VortexCompiler.IsValidDownloadsFolder(path));
            StagingLocation.AdditionalError = this.WhenAny(x => x.StagingLocation.TargetPath)
                                              .Select(path => path == null ? ErrorResponse.Success : VortexCompiler.IsValidBaseStagingFolder(path));
        }
        public CoinViewModel(CoinListViewModel owner, Global global, SmartCoin model)
        {
            Model  = model;
            Owner  = owner;
            Global = global;
            InCoinJoinContainer = owner.CoinListContainerType == CoinListContainerType.CoinJoinTabViewModel;

            RefreshSmartCoinStatus();

            Disposables = new CompositeDisposable();

            _coinJoinInProgress = Model
                                  .WhenAnyValue(x => x.CoinJoinInProgress)
                                  .ToProperty(this, x => x.CoinJoinInProgress, scheduler: RxApp.MainThreadScheduler)
                                  .DisposeWith(Disposables);

            _unspent = Model
                       .WhenAnyValue(x => x.Unspent)
                       .ToProperty(this, x => x.Unspent, scheduler: RxApp.MainThreadScheduler)
                       .DisposeWith(Disposables);

            _confirmed = Model
                         .WhenAnyValue(x => x.Confirmed)
                         .ToProperty(this, x => x.Confirmed, scheduler: RxApp.MainThreadScheduler)
                         .DisposeWith(Disposables);

            _cluster = Model
                       .WhenAnyValue(x => x.Clusters, x => x.Clusters.Labels)
                       .Select(x => x.Item2.ToString())
                       .ToProperty(this, x => x.Clusters, scheduler: RxApp.MainThreadScheduler)
                       .DisposeWith(Disposables);

            _unavailable = Model
                           .WhenAnyValue(x => x.Unavailable)
                           .ToProperty(this, x => x.Unavailable, scheduler: RxApp.MainThreadScheduler)
                           .DisposeWith(Disposables);

            this.WhenAnyValue(x => x.Status)
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(_ => this.RaisePropertyChanged(nameof(ToolTip)));

            Observable
            .Merge(Model.WhenAnyValue(x => x.IsBanned, x => x.SpentAccordingToBackend, x => x.Confirmed, x => x.CoinJoinInProgress).Select(_ => Unit.Default))
            .Merge(Observable.FromEventPattern(Global.ChaumianClient, nameof(Global.ChaumianClient.StateUpdated)).Select(_ => Unit.Default))
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(_ => RefreshSmartCoinStatus())
            .DisposeWith(Disposables);

            Global.BitcoinStore.SmartHeaderChain
            .WhenAnyValue(x => x.TipHeight).Select(_ => Unit.Default)
            .Merge(Model.WhenAnyValue(x => x.Height).Select(_ => Unit.Default))
            .Throttle(TimeSpan.FromSeconds(0.1))                     // DO NOT TAKE THIS THROTTLE OUT, OTHERWISE SYNCING WITH COINS IN THE WALLET WILL STACKOVERFLOW!
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(_ => this.RaisePropertyChanged(nameof(Confirmations)))
            .DisposeWith(Disposables);

            Global.UiConfig
            .WhenAnyValue(x => x.LurkingWifeMode)
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(_ =>
            {
                this.RaisePropertyChanged(nameof(AmountBtc));
                this.RaisePropertyChanged(nameof(Clusters));
            }).DisposeWith(Disposables);

            DequeueCoin = ReactiveCommand.Create(() => Owner.PressDequeue(Model), this.WhenAnyValue(x => x.CoinJoinInProgress));

            _expandMenuCaption = this
                                 .WhenAnyValue(x => x.IsExpanded)
                                 .Select(x => (x ? "Hide " : "Show ") + "Details")
                                 .ObserveOn(RxApp.MainThreadScheduler)
                                 .ToProperty(this, x => x.ExpandMenuCaption)
                                 .DisposeWith(Disposables);

            ToggleDetails = ReactiveCommand.Create(() => IsExpanded = !IsExpanded);

            ToggleDetails.ThrownExceptions
            .ObserveOn(RxApp.TaskpoolScheduler)
            .Subscribe(ex =>
            {
                NotificationHelpers.Error(ex.ToTypeMessageString());
                Logging.Logger.LogWarning(ex);
            });

            DequeueCoin.ThrownExceptions
            .ObserveOn(RxApp.TaskpoolScheduler)
            .Subscribe(ex => Logging.Logger.LogError(ex));                     // Don't notify about it. Dequeue failure (and success) is notified by other mechanism.
        }
Esempio n. 34
0
        public ProviderViewModel(
            CreateFolderViewModelFactory createFolder,
            RenameFileViewModelFactory createRename,
            FileViewModelFactory createFile,
            IAuthViewModel authViewModel,
            IFileManager fileManager,
            IProvider provider,
            IScheduler current,
            IScheduler main)
        {
            _provider = provider;
            Folder    = createFolder(this);
            Rename    = createRename(this);

            var canInteract = this
                              .WhenAnyValue(
                x => x.Folder.IsVisible,
                x => x.Rename.IsVisible,
                (folder, rename) => !folder && !rename);

            _canInteract = canInteract
                           .DistinctUntilChanged()
                           .ToProperty(this, x => x.CanInteract, scheduler: current);

            _refresh = ReactiveCommand.CreateFromTask(
                () => provider.Get(CurrentPath),
                canInteract, main);

            _files = _refresh
                     .Select(files => files
                             .Select(file => createFile(file, this))
                             .OrderByDescending(file => file.IsFolder)
                             .ThenBy(file => file.Name)
                             .ToList())
                     .StartWithEmpty()
                     .Where(files => Files == null ||
                            files.Count != Files.Count() ||
                            !files.All(x => Files.Any(y => x.Path == y.Path &&
                                                      x.Modified == y.Modified)))
                     .ToProperty(this, x => x.Files, scheduler: current);

            _isLoading = _refresh
                         .IsExecuting
                         .ToProperty(this, x => x.IsLoading, scheduler: current);

            _isReady = _refresh
                       .IsExecuting
                       .Select(executing => !executing)
                       .Skip(1)
                       .ToProperty(this, x => x.IsReady, scheduler: current);

            var canOpenCurrentPath = this
                                     .WhenAnyValue(x => x.SelectedFile)
                                     .Select(file => file != null && file.IsFolder)
                                     .CombineLatest(_refresh.IsExecuting, (folder, busy) => folder && !busy)
                                     .CombineLatest(canInteract, (open, interact) => open && interact);

            _open = ReactiveCommand.Create(
                () => Path.Combine(CurrentPath, SelectedFile.Name),
                canOpenCurrentPath, main);

            var canCurrentPathGoBack = this
                                       .WhenAnyValue(x => x.CurrentPath)
                                       .Select(path => path.Length > provider.InitialPath.Length)
                                       .CombineLatest(_refresh.IsExecuting, (valid, busy) => valid && !busy)
                                       .CombineLatest(canInteract, (back, interact) => back && interact);

            _back = ReactiveCommand.Create(
                () => Path.GetDirectoryName(CurrentPath),
                canCurrentPathGoBack, main);

            _currentPath = _open
                           .Merge(_back)
                           .DistinctUntilChanged()
                           .Log(this, $"Current path changed in {provider.Name}")
                           .ToProperty(this, x => x.CurrentPath, provider.InitialPath, scheduler: current);

            this.WhenAnyValue(x => x.CurrentPath)
            .Skip(1)
            .Select(path => Unit.Default)
            .InvokeCommand(_refresh);

            this.WhenAnyValue(x => x.CurrentPath)
            .Subscribe(path => SelectedFile = null);

            _isCurrentPathEmpty = this
                                  .WhenAnyValue(x => x.Files)
                                  .Skip(1)
                                  .Where(files => files != null)
                                  .Select(files => !files.Any())
                                  .ToProperty(this, x => x.IsCurrentPathEmpty, scheduler: current);

            _hasErrors = _refresh
                         .ThrownExceptions
                         .Select(exception => true)
                         .Merge(_refresh.Select(x => false))
                         .ToProperty(this, x => x.HasErrors, scheduler: current);

            var canUploadToCurrentPath = this
                                         .WhenAnyValue(x => x.CurrentPath)
                                         .Select(path => path != null)
                                         .CombineLatest(_refresh.IsExecuting, (up, loading) => up && !loading)
                                         .CombineLatest(canInteract, (upload, interact) => upload && interact);

            _uploadToCurrentPath = ReactiveCommand.CreateFromObservable(
                () => Observable
                .FromAsync(fileManager.OpenRead)
                .Where(response => response.Name != null && response.Stream != null)
                .Select(x => _provider.UploadFile(CurrentPath, x.Stream, x.Name))
                .SelectMany(task => task.ToObservable()),
                canUploadToCurrentPath,
                main);

            _uploadToCurrentPath.InvokeCommand(_refresh);

            var canDownloadSelectedFile = this
                                          .WhenAnyValue(x => x.SelectedFile)
                                          .Select(file => file != null && !file.IsFolder)
                                          .CombineLatest(_refresh.IsExecuting, (down, loading) => down && !loading)
                                          .CombineLatest(canInteract, (download, interact) => download && interact);

            _downloadSelectedFile = ReactiveCommand.CreateFromObservable(
                () => Observable
                .FromAsync(() => fileManager.OpenWrite(SelectedFile.Name))
                .Where(stream => stream != null)
                .Select(stream => _provider.DownloadFile(SelectedFile.Path, stream))
                .SelectMany(task => task.ToObservable()),
                canDownloadSelectedFile,
                main);

            var isAuthEnabled = provider.SupportsDirectAuth || provider.SupportsOAuth;
            var canLogout     = provider
                                .IsAuthorized
                                .Select(loggedIn => loggedIn && isAuthEnabled)
                                .DistinctUntilChanged()
                                .CombineLatest(canInteract, (logout, interact) => logout && interact)
                                .ObserveOn(main);

            _logout    = ReactiveCommand.CreateFromTask(provider.Logout, canLogout);
            _canLogout = canLogout
                         .ToProperty(this, x => x.CanLogout, scheduler: current);

            var canDeleteSelection = this
                                     .WhenAnyValue(x => x.SelectedFile)
                                     .Select(file => file != null && !file.IsFolder)
                                     .CombineLatest(_refresh.IsExecuting, (del, loading) => del && !loading)
                                     .CombineLatest(canInteract, (delete, interact) => delete && interact);

            _deleteSelectedFile = ReactiveCommand.CreateFromTask(
                () => provider.Delete(SelectedFile.Path, SelectedFile.IsFolder),
                canDeleteSelection);

            _deleteSelectedFile.InvokeCommand(Refresh);

            var canUnselectFile = this
                                  .WhenAnyValue(x => x.SelectedFile)
                                  .Select(selection => selection != null)
                                  .CombineLatest(_refresh.IsExecuting, (sel, loading) => sel && !loading)
                                  .CombineLatest(canInteract, (unselect, interact) => unselect && interact);

            _unselectFile = ReactiveCommand.Create(
                () => { SelectedFile = null; },
                canUnselectFile);

            _uploadToCurrentPath
            .ThrownExceptions
            .Merge(_deleteSelectedFile.ThrownExceptions)
            .Merge(_downloadSelectedFile.ThrownExceptions)
            .Merge(_refresh.ThrownExceptions)
            .Log(this, $"Exception occured in provider {provider.Name}")
            .Subscribe();

            Auth      = authViewModel;
            Activator = new ViewModelActivator();
            this.WhenActivated(disposable =>
            {
                this.WhenAnyValue(x => x.Auth.IsAuthenticated)
                .Where(authenticated => authenticated)
                .Select(ignore => Unit.Default)
                .InvokeCommand(_refresh)
                .DisposeWith(disposable);

                var interval = TimeSpan.FromSeconds(1);
                Observable.Timer(interval, interval)
                .Select(unit => RefreshingIn - 1)
                .Where(value => value >= 0)
                .ObserveOn(main)
                .Subscribe(x => RefreshingIn = x)
                .DisposeWith(disposable);

                this.WhenAnyValue(x => x.RefreshingIn)
                .Skip(1)
                .Where(refreshing => refreshing == 0)
                .Log(this, $"Refreshing provider {provider.Name} path {CurrentPath}")
                .Select(value => Unit.Default)
                .InvokeCommand(_refresh)
                .DisposeWith(disposable);

                const int refreshPeriod = 30;
                _refresh.Select(results => refreshPeriod)
                .StartWith(refreshPeriod)
                .Subscribe(x => RefreshingIn = x)
                .DisposeWith(disposable);

                this.WhenAnyValue(x => x.CanInteract)
                .Skip(1)
                .Where(interact => interact)
                .Select(x => Unit.Default)
                .InvokeCommand(_refresh);
            });
        }
        public PullRequestCreationViewModel(
            IModelServiceFactory modelServiceFactory,
            IPullRequestService service,
            INotificationService notifications)
        {
            Guard.ArgumentNotNull(modelServiceFactory, nameof(modelServiceFactory));
            Guard.ArgumentNotNull(service, nameof(service));
            Guard.ArgumentNotNull(notifications, nameof(notifications));

            this.service             = service;
            this.modelServiceFactory = modelServiceFactory;

            this.WhenAnyValue(x => x.Branches)
            .WhereNotNull()
            .Where(_ => TargetBranch != null)
            .Subscribe(x =>
            {
                if (!x.Any(t => t.Equals(TargetBranch)))
                {
                    TargetBranch = GitHubRepository.IsFork ? GitHubRepository.Parent.DefaultBranch : GitHubRepository.DefaultBranch;
                }
            });

            SetupValidators();

            var whenAnyValidationResultChanges = this.WhenAny(
                x => x.TitleValidator.ValidationResult,
                x => x.BranchValidator.ValidationResult,
                x => x.IsBusy,
                (x, y, z) => (x.Value?.IsValid ?? false) && (y.Value?.IsValid ?? false) && !z.Value);

            this.WhenAny(x => x.BranchValidator.ValidationResult, x => x.GetValue())
            .WhereNotNull()
            .Where(x => !x.IsValid && x.DisplayValidationError)
            .Subscribe(x => notifications.ShowError(BranchValidator.ValidationResult.Message));

            CreatePullRequest = ReactiveCommand.CreateAsyncObservable(whenAnyValidationResultChanges,
                                                                      _ => service
                                                                      .CreatePullRequest(modelService, activeLocalRepo, TargetBranch.Repository, SourceBranch, TargetBranch, PRTitle, Description ?? String.Empty)
                                                                      .Catch <IPullRequestModel, Exception>(ex =>
            {
                log.Error(ex, "Error creating pull request");

                //TODO:Will need a uniform solution to HTTP exception message handling
                var apiException = ex as ApiValidationException;
                var error        = apiException?.ApiError?.Errors?.FirstOrDefault();
                notifications.ShowError(error?.Message ?? ex.Message);
                return(Observable.Empty <IPullRequestModel>());
            }))
                                .OnExecuteCompleted(pr =>
            {
                notifications.ShowMessage(String.Format(CultureInfo.CurrentCulture, Resources.PRCreatedUpstream, SourceBranch.DisplayName, TargetBranch.Repository.Owner + "/" + TargetBranch.Repository.Name + "#" + pr.Number,
                                                        TargetBranch.Repository.CloneUrl.ToRepositoryUrl().Append("pull/" + pr.Number)));
                NavigateTo("/pulls?refresh=true");
                Cancel.Execute(null);
            });

            Cancel = ReactiveCommand.Create();

            isExecuting = CreatePullRequest.IsExecuting.ToProperty(this, x => x.IsExecuting);

            this.WhenAnyValue(x => x.Initialized, x => x.GitHubRepository, x => x.IsExecuting)
            .Select(x => !(x.Item1 && x.Item2 != null && !x.Item3))
            .Subscribe(x => IsBusy = x);
        }
Esempio n. 36
0
        public SolutionPatcherVM(ProfileVM parent, SolutionPatcherSettings?settings = null)
            : base(parent, settings)
        {
            CopyInSettings(settings);
            SolutionPath.Filters.Add(new CommonFileDialogFilter("Solution", ".sln"));
            SelectedProjectPath.Filters.Add(new CommonFileDialogFilter("Project", ".csproj"));

            _DisplayName = Observable.CombineLatest(
                this.WhenAnyValue(x => x.Nickname),
                this.WhenAnyValue(x => x.SelectedProjectPath.TargetPath)
                .StartWith(settings?.ProjectSubpath ?? string.Empty),
                (nickname, path) =>
            {
                if (!string.IsNullOrWhiteSpace(nickname))
                {
                    return(nickname);
                }
                try
                {
                    var name = Path.GetFileName(Path.GetDirectoryName(path));
                    if (string.IsNullOrWhiteSpace(name))
                    {
                        return(string.Empty);
                    }
                    return(name);
                }
                catch (Exception)
                {
                    return(string.Empty);
                }
            })
                           .ToProperty(this, nameof(DisplayName), Nickname);

            AvailableProjects = SolutionPatcherConfigLogic.AvailableProject(
                this.WhenAnyValue(x => x.SolutionPath.TargetPath))
                                .ObserveOnGui()
                                .ToObservableCollection(this);

            var projPath = SolutionPatcherConfigLogic.ProjectPath(
                solutionPath: this.WhenAnyValue(x => x.SolutionPath.TargetPath),
                projectSubpath: this.WhenAnyValue(x => x.ProjectSubpath));

            projPath
            .Subscribe(p => SelectedProjectPath.TargetPath = p)
            .DisposeWith(this);

            _State = Observable.CombineLatest(
                this.WhenAnyValue(x => x.SolutionPath.ErrorState),
                this.WhenAnyValue(x => x.SelectedProjectPath.ErrorState),
                this.WhenAnyValue(x => x.Profile.Config.MainVM)
                .Select(x => x.DotNetSdkInstalled)
                .Switch(),
                (sln, proj, dotnet) =>
            {
                if (sln.Failed)
                {
                    return(new ConfigurationState(sln));
                }
                if (dotnet == null)
                {
                    return(new ConfigurationState(ErrorResponse.Fail("No dotnet SDK installed")));
                }
                return(new ConfigurationState(proj));
            })
                     .ToGuiProperty <ConfigurationState>(this, nameof(State), new ConfigurationState(ErrorResponse.Fail("Evaluating"))
            {
                IsHaltingError = false
            });

            OpenSolutionCommand = ReactiveCommand.Create(
                canExecute: this.WhenAnyValue(x => x.SolutionPath.InError)
                .Select(x => !x),
                execute: () =>
            {
                try
                {
                    Process.Start(new ProcessStartInfo(SolutionPath.TargetPath)
                    {
                        UseShellExecute = true,
                    });
                }
                catch (Exception ex)
                {
                    Log.Logger.Error(ex, $"Error opening solution: {SolutionPath.TargetPath}");
                }
            });

            var metaPath = this.WhenAnyValue(x => x.SelectedProjectPath.TargetPath)
                           .Select(projPath =>
            {
                try
                {
                    return(Path.Combine(Path.GetDirectoryName(projPath) !, Constants.MetaFileName));
                }
                catch (Exception)
                {
                    return(string.Empty);
                }
            })
                           .Replay(1)
                           .RefCount();

            // Set up meta file sync
            metaPath
            .Select(path =>
            {
                return(Noggog.ObservableExt.WatchFile(path)
                       .StartWith(Unit.Default)
                       .Throttle(TimeSpan.FromMilliseconds(500), RxApp.MainThreadScheduler)
                       .Select(_ =>
                {
                    if (!File.Exists(path))
                    {
                        return default;
                    }
                    try
                    {
                        return JsonConvert.DeserializeObject <PatcherCustomization>(
                            File.ReadAllText(path),
                            Execution.Constants.JsonSettings);
                    }
                    catch (Exception ex)
                    {
                        Logger.Error(ex, "Error reading in meta");
                    }
                    return default(PatcherCustomization?);
                }));
            })
            .Switch()
            .DistinctUntilChanged()
            .ObserveOnGui()
            .Subscribe(info =>
            {
                if (info == null)
                {
                    return;
                }
                if (info.Nickname != null)
                {
                    this.Nickname = info.Nickname;
                }
                this.LongDescription  = info.LongDescription ?? string.Empty;
                this.ShortDescription = info.OneLineDescription ?? string.Empty;
                this.Visibility       = info.Visibility;
                this.Versioning       = info.PreferredAutoVersioning;
                this.RequiredMods.SetTo(info.RequiredMods
                                        .SelectWhere(x => TryGet <ModKey> .Create(ModKey.TryFromNameAndExtension(x, out var modKey), modKey))
                                        .Select(m => new ModKeyItemViewModel(m)));
            })
            .DisposeWith(this);

            Observable.CombineLatest(
                this.WhenAnyValue(x => x.DisplayName),
                this.WhenAnyValue(x => x.ShortDescription),
                this.WhenAnyValue(x => x.LongDescription),
                this.WhenAnyValue(x => x.Visibility),
                this.WhenAnyValue(x => x.Versioning),
                this.RequiredMods
                .ToObservableChangeSet()
                .Transform(x => x.ModKey)
                .AddKey(x => x)
                .Sort(ModKey.Alphabetical, SortOptimisations.ComparesImmutableValuesOnly, resetThreshold: 0)
                .QueryWhenChanged()
                .Select(x => x.Items)
                .StartWith(Enumerable.Empty <ModKey>()),
                metaPath,
                (nickname, shortDesc, desc, visibility, versioning, reqMods, meta) => (nickname, shortDesc, desc, visibility, versioning, reqMods: reqMods.Select(x => x.FileName).OrderBy(x => x).ToArray(), meta))
            .DistinctUntilChanged()
            .Throttle(TimeSpan.FromMilliseconds(200), RxApp.MainThreadScheduler)
            .Skip(1)
            .Subscribe(x =>
            {
                try
                {
                    if (string.IsNullOrWhiteSpace(x.meta))
                    {
                        return;
                    }
                    File.WriteAllText(x.meta,
                                      JsonConvert.SerializeObject(
                                          new PatcherCustomization()
                    {
                        OneLineDescription      = x.shortDesc,
                        LongDescription         = x.desc,
                        Visibility              = x.visibility,
                        Nickname                = x.nickname,
                        PreferredAutoVersioning = x.versioning,
                        RequiredMods            = x.reqMods
                    },
                                          Formatting.Indented,
                                          Execution.Constants.JsonSettings));
                }
                catch (Exception ex)
                {
                    Logger.Error(ex, "Error writing out meta");
                }
            })
            .DisposeWith(this);

            ReloadAutogeneratedSettingsCommand = ReactiveCommand.Create(() => { });
            PatcherSettings = new PatcherSettingsVM(
                Logger,
                this,
                projPath
                .Merge(ReloadAutogeneratedSettingsCommand.EndingExecution()
                       .WithLatestFrom(projPath, (_, p) => p))
                .Select(p => GetResponse <string> .Succeed(p)),
                needBuild: true)
                              .DisposeWith(this);
        }
Esempio n. 37
0
        public GitHubPaneViewModel(
            IViewViewModelFactory viewModelFactory,
            ISimpleApiClientFactory apiClientFactory,
            IConnectionManager connectionManager,
            ITeamExplorerContext teamExplorerContext,
            IVisualStudioBrowser browser,
            IUsageTracker usageTracker,
            INavigationViewModel navigator,
            ILoggedOutViewModel loggedOut,
            INotAGitHubRepositoryViewModel notAGitHubRepository,
            INotAGitRepositoryViewModel notAGitRepository)
        {
            Guard.ArgumentNotNull(viewModelFactory, nameof(viewModelFactory));
            Guard.ArgumentNotNull(apiClientFactory, nameof(apiClientFactory));
            Guard.ArgumentNotNull(connectionManager, nameof(connectionManager));
            Guard.ArgumentNotNull(teamExplorerContext, nameof(teamExplorerContext));
            Guard.ArgumentNotNull(browser, nameof(browser));
            Guard.ArgumentNotNull(usageTracker, nameof(usageTracker));
            Guard.ArgumentNotNull(navigator, nameof(navigator));
            Guard.ArgumentNotNull(loggedOut, nameof(loggedOut));
            Guard.ArgumentNotNull(notAGitHubRepository, nameof(notAGitHubRepository));
            Guard.ArgumentNotNull(notAGitRepository, nameof(notAGitRepository));

            this.viewModelFactory     = viewModelFactory;
            this.apiClientFactory     = apiClientFactory;
            this.connectionManager    = connectionManager;
            this.teamExplorerContext  = teamExplorerContext;
            this.browser              = browser;
            this.usageTracker         = usageTracker;
            this.navigator            = navigator;
            this.loggedOut            = loggedOut;
            this.notAGitHubRepository = notAGitHubRepository;
            this.notAGitRepository    = notAGitRepository;

            var contentAndNavigatorContent = Observable.CombineLatest(
                this.WhenAnyValue(x => x.Content),
                navigator.WhenAnyValue(x => x.Content),
                (c, nc) => new { Content = c, NavigatorContent = nc });

            contentOverride = contentAndNavigatorContent
                              .SelectMany(x =>
            {
                if (x.Content == null)
                {
                    return(Observable.Return(ContentOverride.Spinner));
                }
                else if (x.Content == navigator && x.NavigatorContent != null)
                {
                    return(x.NavigatorContent.WhenAnyValue(
                               y => y.IsLoading,
                               y => y.Error,
                               (l, e) =>
                    {
                        if (l)
                        {
                            return ContentOverride.Spinner;
                        }
                        if (e != null)
                        {
                            return ContentOverride.Error;
                        }
                        else
                        {
                            return ContentOverride.None;
                        }
                    }));
                }
                else
                {
                    return(Observable.Return(ContentOverride.None));
                }
            })
                              .ToProperty(this, x => x.ContentOverride);

            // Returns navigator.Content if Content == navigator, otherwise null.
            var currentPage = contentAndNavigatorContent
                              .Select(x => x.Content == navigator ? x.NavigatorContent : null);

            title = currentPage
                    .SelectMany(x => x?.WhenAnyValue(y => y.Title) ?? Observable.Return <string>(null))
                    .Select(x => x ?? "GitHub")
                    .ToProperty(this, x => x.Title);

            isSearchEnabled = currentPage
                              .Select(x => x is ISearchablePageViewModel)
                              .ToProperty(this, x => x.IsSearchEnabled);

            refresh = ReactiveCommand.CreateAsyncTask(
                currentPage.SelectMany(x => x?.WhenAnyValue(
                                           y => y.IsLoading,
                                           y => y.IsBusy,
                                           (loading, busy) => !loading && !busy)
                                       ?? Observable.Return(false)),
                _ => navigator.Content.Refresh());
            refresh.ThrownExceptions.Subscribe();

            showPullRequests = ReactiveCommand.CreateAsyncTask(
                this.WhenAny(x => x.Content, x => x.Value == navigator),
                _ => ShowPullRequests());

            openInBrowser = ReactiveCommand.Create(currentPage.Select(x => x is IOpenInBrowser));
            openInBrowser.Subscribe(_ =>
            {
                var url = ((IOpenInBrowser)navigator.Content).WebUrl;
                if (url != null)
                {
                    browser.OpenUrl(url);
                }
            });

            navigator.WhenAnyObservable(x => x.Content.NavigationRequested)
            .Subscribe(x => NavigateTo(x).Forget());

            this.WhenAnyValue(x => x.SearchQuery)
            .Where(x => navigator.Content is ISearchablePageViewModel)
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(x => ((ISearchablePageViewModel)navigator.Content).SearchQuery = x);
        }
Esempio n. 38
0
        public ReleaseViewModel(IApplicationService applicationService,
                                IUrlRouterService urlRouterService, IActionMenuFactory actionMenuService)
        {
            this.WhenAnyValue(x => x.ReleaseModel)
            .Select(x =>
            {
                if (x == null)
                {
                    return("Release");
                }
                var name = string.IsNullOrEmpty(x.Name) ? x.TagName : x.Name;
                return(name ?? "Release");
            })
            .Subscribe(x => Title = x);

            var shareCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.ReleaseModel).Select(x => x != null));

            shareCommand.Subscribe(_ => actionMenuService.ShareUrl(ReleaseModel.HtmlUrl));

            var gotoUrlCommand = new Action <string>(x =>
            {
                var vm = this.CreateViewModel <WebBrowserViewModel>();
                vm.Url = x;
                NavigateTo(vm);
            });

            var gotoGitHubCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.ReleaseModel).Select(x => x != null));

            gotoGitHubCommand.Select(_ => ReleaseModel.HtmlUrl).Subscribe(gotoUrlCommand);

            GoToLinkCommand = ReactiveCommand.Create();
            GoToLinkCommand.OfType <string>().Subscribe(x =>
            {
                var handledViewModel = urlRouterService.Handle(x);
                if (handledViewModel != null)
                {
                    NavigateTo(handledViewModel);
                }
                else
                {
                    gotoUrlCommand(x);
                }
            });

            var canShowMenu = this.WhenAnyValue(x => x.ReleaseModel).Select(x => x != null);

            ShowMenuCommand = ReactiveCommand.CreateAsyncTask(canShowMenu, _ =>
            {
                var menu = actionMenuService.Create(Title);
                menu.AddButton("Share", shareCommand);
                menu.AddButton("Show in GitHub", gotoGitHubCommand);
                return(menu.Show());
            });

            _contentText = this.WhenAnyValue(x => x.ReleaseModel).IsNotNull()
                           .Select(x => x.BodyHtml).ToProperty(this, x => x.ContentText);

            LoadCommand = ReactiveCommand.CreateAsyncTask(x =>
                                                          this.RequestModel(applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].GetRelease(ReleaseId),
                                                                            x as bool?, r => ReleaseModel = r.Data));
        }
Esempio n. 39
0
        public SurveyViewModel()
        {
            ExecuteTracePull = ReactiveCommand.CreateFromTask <string, List <TraceInfo> >(
                MaxDataPoint => GetMaxDataFromTrace(MaxDataPoint)
                );

            /* Creating our UI declaratively
             *
             * The Properties in this ViewModel are related to each other in different
             * ways - with other frameworks, it is difficult to describe each relation
             * succinctly; the code to implement "The UI spinner spins while the search
             * is live" usually ends up spread out over several event handlers.
             *
             * However, with RxUI, we can describe how properties are related in a very
             * organized clear way. Let's describe the workflow of what the user does in
             * this application, in the order they do it.
             */

            // We're going to take a Property and turn it into an Observable here - this
            // Observable will yield a value every time the Search term changes (which in
            // the XAML, is connected to the TextBox).
            //
            // We're going to use the Throttle operator to ignore changes that
            // happen too quickly, since we don't want to issue a search for each
            // key pressed! We then pull the Value of the change, then filter
            // out changes that are identical, as well as strings that are empty.
            //
            // Finally, we use RxUI's InvokeCommand operator, which takes the String
            // and calls the Execute method on the ExecuteSearch Command, after
            // making sure the Command can be executed via calling CanExecute.
            this.WhenAnyValue(x => x.TraceNumber)
            .Throttle(TimeSpan.FromMilliseconds(80), RxApp.MainThreadScheduler)
            .Select(x => x.ToString())
            .DistinctUntilChanged()
            .Where(x => !String.IsNullOrWhiteSpace(x))
            .InvokeCommand(ExecuteTracePull);

            // How would we describe when to show the spinner in English? We
            // might say something like, "The spinner's visibility is whether
            // the search is running". RxUI lets us write these kinds of
            // statements in code.
            //
            // ExecuteSearch has an IObservable<bool> called IsExecuting that
            // fires every time the command changes execution state. We Select() that into
            // a Visibility then we will use RxUI's
            // ToProperty operator, which is a helper to create an
            // ObservableAsPropertyHelper object.

            _SpinnerVisibility = ExecuteTracePull.IsExecuting
                                 .Select(x => x ? Visibility.Visible : Visibility.Collapsed)
                                 .ToProperty(this, x => x.SpinnerVisibility, Visibility.Hidden);

            // We subscribe to the "ThrownExceptions" property of our ReactiveCommand,
            // where ReactiveUI pipes any exceptions that are thrown in
            // "GetSearchResultsFromFlickr" into. See the "Error Handling" section
            // for more information about this.
            ExecuteTracePull.ThrownExceptions.Subscribe(ex => { /* Handle errors here */ });

            // Here, we're going to actually describe what happens when the Command
            // gets invoked - we're going to run the GetSearchResultsFromFlickr every
            // time the Command is executed.
            //
            // The important bit here is the return value - an Observable. We're going
            // to end up here with a Stream of FlickrPhoto Lists: every time someone
            // calls Execute, we eventually end up with a new list which we then
            // immediately put into the SearchResults property, that will then
            // automatically fire INotifyPropertyChanged.
            _traceResults = ExecuteTracePull.ToProperty(this, x => x.TraceResults, new List <TraceInfo>());
        }
        public void Initialize(NodesCollection nodes, WasabiSynchronizer synchronizer, UpdateChecker updateChecker)
        {
            Nodes        = nodes;
            Synchronizer = synchronizer;
            HashChain    = synchronizer.BitcoinStore.HashChain;
            UseTor       = Global.Config.UseTor.Value;       // Don't make it dynamic, because if you change this config settings only next time will it activate.

            _status = ActiveStatuses.WhenAnyValue(x => x.CurrentStatus)
                      .ObserveOn(RxApp.MainThreadScheduler)
                      .ToProperty(this, x => x.Status)
                      .DisposeWith(Disposables);

            Observable.FromEventPattern <NodeEventArgs>(nodes, nameof(nodes.Added))
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(x =>
            {
                SetPeers(Nodes.Count);
            }).DisposeWith(Disposables);

            Observable.FromEventPattern <NodeEventArgs>(nodes, nameof(nodes.Removed))
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(x =>
            {
                SetPeers(Nodes.Count);
            }).DisposeWith(Disposables);

            SetPeers(Nodes.Count);

            Observable.FromEventPattern <bool>(typeof(WalletService), nameof(WalletService.DownloadingBlockChanged))
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(x => DownloadingBlock = x.EventArgs)
            .DisposeWith(Disposables);

            Synchronizer.WhenAnyValue(x => x.TorStatus)
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(status =>
            {
                SetTor(status);
                SetPeers(Nodes.Count);
            }).DisposeWith(Disposables);

            Synchronizer.WhenAnyValue(x => x.BackendStatus)
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(_ =>
            {
                Backend = Synchronizer.BackendStatus;
            }).DisposeWith(Disposables);

            _filtersLeft = HashChain.WhenAnyValue(x => x.HashesLeft)
                           .Throttle(TimeSpan.FromMilliseconds(100))
                           .ObserveOn(RxApp.MainThreadScheduler)
                           .ToProperty(this, x => x.FiltersLeft)
                           .DisposeWith(Disposables);

            Synchronizer.WhenAnyValue(x => x.UsdExchangeRate)
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(usd =>
            {
                BtcPrice = $"${(long)usd}";
            }).DisposeWith(Disposables);

            Observable.FromEventPattern <bool>(Synchronizer, nameof(Synchronizer.ResponseArrivedIsGenSocksServFail))
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(e =>
            {
                OnResponseArrivedIsGenSocksServFail(e.EventArgs);
            }).DisposeWith(Disposables);

            this.WhenAnyValue(x => x.FiltersLeft, x => x.DownloadingBlock)
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(tup =>
            {
                (int filtersLeft, bool downloadingBlock) = tup.ToValueTuple();
                if (filtersLeft == 0 && !downloadingBlock)
                {
                    TryRemoveStatus(StatusBarStatus.Synchronizing);
                }
                else
                {
                    TryAddStatus(StatusBarStatus.Synchronizing);
                }
            });

            this.WhenAnyValue(x => x.Tor, x => x.Backend, x => x.Peers)
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(tup =>
            {
                (TorStatus tor, BackendStatus backend, int peers) = tup.ToValueTuple();
                if (tor == TorStatus.NotRunning || backend != BackendStatus.Connected || peers < 1)
                {
                    TryAddStatus(StatusBarStatus.Connecting);
                }
                else
                {
                    TryRemoveStatus(StatusBarStatus.Connecting);
                }
            });

            this.WhenAnyValue(x => x.UpdateStatus)
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(x =>
            {
                if (x == UpdateStatus.Critical)
                {
                    TryAddStatus(StatusBarStatus.CriticalUpdate);
                }
                else
                {
                    TryRemoveStatus(StatusBarStatus.CriticalUpdate);
                }

                if (x == UpdateStatus.Optional)
                {
                    TryAddStatus(StatusBarStatus.OptionalUpdate);
                }
                else
                {
                    TryRemoveStatus(StatusBarStatus.OptionalUpdate);
                }
            });

            UpdateCommand = ReactiveCommand.Create(() =>
            {
                try
                {
                    IoHelpers.OpenBrowser("https://wasabiwallet.io/#download");
                }
                catch (Exception ex)
                {
                    Logging.Logger.LogWarning <StatusBarViewModel>(ex);
                    IoC.Get <IShell>().AddOrSelectDocument(() => new AboutViewModel(Global));
                }
            }, this.WhenAnyValue(x => x.UpdateStatus)
                                                   .ObserveOn(RxApp.MainThreadScheduler)
                                                   .Select(x => x != UpdateStatus.Latest));
            this.RaisePropertyChanged(nameof(UpdateCommand));             // The binding happens after the constructor. So, if the command is not in constructor, then we need this line.

            updateChecker.Start(TimeSpan.FromMinutes(7),
                                () =>
            {
                UpdateStatus = UpdateStatus.Critical;
                return(Task.CompletedTask);
            },
                                () =>
            {
                if (UpdateStatus != UpdateStatus.Critical)
                {
                    UpdateStatus = UpdateStatus.Optional;
                }
                return(Task.CompletedTask);
            });
        }
Esempio n. 41
0
        protected SongSourceViewModel(Library library, CoreSettings coreSettings, Guid accessToken)
        {
            if (library == null)
            {
                throw new ArgumentNullException("library");
            }

            if (coreSettings == null)
            {
                throw new ArgumentNullException("coreSettings");
            }

            this.library      = library;
            this.CoreSettings = coreSettings;

            this.searchText      = String.Empty;
            this.selectableSongs = Enumerable.Empty <T>();

            this.ApplyOrder(SortHelpers.GetOrderByTitle <T>, ref this.titleOrder);

            IObservable <bool> canAddToPlaylist = this.WhenAnyValue(x => x.SelectedSongs, x => x.Any())
                                                  .CombineLatest(this.Library.LocalAccessControl.HasAccess(this.CoreSettings.WhenAnyValue(x => x.LockPlaylist), accessToken), (songsSelected, hasAccess) => songsSelected && hasAccess);

            this.AddToPlaylistCommand = ReactiveCommand.Create(canAddToPlaylist);
            this.AddToPlaylistCommand.Subscribe(x =>
            {
                if (this.IsAdmin)
                {
                    this.library.AddSongsToPlaylist(this.SelectedSongs.Select(song => song.Model), accessToken);

                    if (x != null)
                    {
                        this.library.MovePlaylistSong(this.library.CurrentPlaylist.Last().Index, (int)x, accessToken);
                    }
                }

                else
                {
                    this.library.AddGuestSongToPlaylist(this.SelectedSongs.Select(song => song.Model).Single(), accessToken);
                }
            });

            this.SelectionChangedCommand = ReactiveCommand.Create();
            this.SelectionChangedCommand.Where(x => x != null)
            .Select(x => ((IEnumerable)x).Cast <ISongViewModelBase>())
            .Subscribe(x => this.SelectedSongs = x);

            this.isAdmin = this.Library.LocalAccessControl.ObserveAccessPermission(accessToken)
                           .Select(x => x == AccessPermission.Admin)
                           .ToProperty(this, x => x.IsAdmin);

            // The default play command differs whether we are in party mode or not and depends on
            // the selected setting in administrator mode and the song source.
            //
            // In party mode, it is always "Add To Playlist", in administrator mode we look at the
            // value that the song source returns
            this.defaultPlaybackCommand = this.WhenAnyValue(x => x.IsAdmin,
                                                            isAdmin => !isAdmin || this.DefaultPlaybackAction == DefaultPlaybackAction.AddToPlaylist ?
                                                            (IReactiveCommand)this.AddToPlaylistCommand : this.PlayNowCommand)
                                          .ToProperty(this, x => x.DefaultPlaybackCommand);

            this.OrderByDurationCommand = ReactiveCommand.Create();
            this.OrderByDurationCommand.Subscribe(_ => this.ApplyOrder(SortHelpers.GetOrderByDuration <T>, ref this.durationOrder));

            this.OrderByTitleCommand = ReactiveCommand.Create();
            this.OrderByTitleCommand.Subscribe(_ => this.ApplyOrder(SortHelpers.GetOrderByTitle <T>, ref this.titleOrder));
        }
Esempio n. 42
0
        public ModListGalleryVM(MainWindowVM mainWindowVM)
            : base(mainWindowVM)
        {
            MWVM = mainWindowVM;

            // load persistent filter settings
            if (settings.IsPersistent)
            {
                GameType         = !string.IsNullOrEmpty(settings.Game) ? settings.Game : ALL_GAME_TYPE;
                ShowNSFW         = settings.ShowNSFW;
                ShowUtilityLists = settings.ShowUtilityLists;
                OnlyInstalled    = settings.OnlyInstalled;
                Search           = settings.Search;
            }
            else
            {
                GameType = ALL_GAME_TYPE;
            }

            // subscribe to save signal
            MWVM.Settings.SaveSignal
            .Subscribe(_ => UpdateFiltersSettings())
            .DisposeWith(this.CompositeDisposable);

            ClearFiltersCommand = ReactiveCommand.Create(
                () =>
            {
                OnlyInstalled    = false;
                ShowNSFW         = false;
                ShowUtilityLists = false;
                Search           = string.Empty;
                GameType         = ALL_GAME_TYPE;
            });


            this.WhenAny(x => x.OnlyInstalled)
            .Subscribe(val =>
            {
                if (val)
                {
                    GameType = ALL_GAME_TYPE;
                }
            })
            .DisposeWith(CompositeDisposable);

            var sourceList = Observable.Return(Unit.Default)
                             .ObserveOn(RxApp.TaskpoolScheduler)
                             .SelectTask(async _ =>
            {
                try
                {
                    Error    = null;
                    var list = await ModlistMetadata.LoadFromGithub();
                    Error    = ErrorResponse.Success;
                    return(list
                           .AsObservableChangeSet(x => x.DownloadMetadata?.Hash ?? Hash.Empty));
                }
                catch (Exception ex)
                {
                    Utils.Error(ex);
                    Error = ErrorResponse.Fail(ex);
                    return(Observable.Empty <IChangeSet <ModlistMetadata, Hash> >());
                }
            })
                             // Unsubscribe and release when not active
                             .FlowSwitch(
                this.WhenAny(x => x.IsActive),
                valueWhenOff: Observable.Return(ChangeSet <ModlistMetadata, Hash> .Empty))
                             .Switch()
                             .RefCount();

            _Loaded = sourceList.CollectionCount()
                      .Select(c => c > 0)
                      .ToProperty(this, nameof(Loaded));

            // Convert to VM and bind to resulting list
            sourceList
            .ObserveOnGuiThread()
            .Transform(m => new ModListMetadataVM(this, m))
            .DisposeMany()
            // Filter only installed
            .Filter(this.WhenAny(x => x.OnlyInstalled)
                    .Select <bool, Func <ModListMetadataVM, bool> >(onlyInstalled => (vm) =>
            {
                if (!onlyInstalled)
                {
                    return(true);
                }
                if (!GameRegistry.Games.TryGetValue(vm.Metadata.Game, out var gameMeta))
                {
                    return(false);
                }
                return(gameMeta.IsInstalled);
            }))
            // Filter on search box
            .Filter(this.WhenAny(x => x.Search)
                    .Debounce(TimeSpan.FromMilliseconds(150), RxApp.MainThreadScheduler)
                    .Select <string, Func <ModListMetadataVM, bool> >(search => (vm) =>
            {
                if (string.IsNullOrWhiteSpace(search))
                {
                    return(true);
                }
                return(vm.Metadata.Title.ContainsCaseInsensitive(search) || vm.Metadata.tags.Any(t => t.ContainsCaseInsensitive(search)));
            }))
            .Filter(this.WhenAny(x => x.ShowNSFW)
                    .Select <bool, Func <ModListMetadataVM, bool> >(showNSFW => vm =>
            {
                if (!vm.Metadata.NSFW)
                {
                    return(true);
                }
                return(vm.Metadata.NSFW && showNSFW);
            }))
            .Filter(this.WhenAny(x => x.ShowUtilityLists)
                    .Select <bool, Func <ModListMetadataVM, bool> >(showUtilityLists => vm => showUtilityLists ? vm.Metadata.UtilityList : !vm.Metadata.UtilityList))
            // Filter by Game
            .Filter(this.WhenAny(x => x.GameType)
                    .Debounce(TimeSpan.FromMilliseconds(150), RxApp.MainThreadScheduler)
                    .Select <string, Func <ModListMetadataVM, bool> >(GameType => (vm) =>
            {
                if (GameType == ALL_GAME_TYPE)
                {
                    return(true);
                }
                if (string.IsNullOrEmpty(GameType))
                {
                    return(false);
                }

                return(GameType == vm.Metadata.Game.GetDescription <Game>().ToString());
            }))
            .Bind(ModLists)
            .Subscribe()
            .DisposeWith(CompositeDisposable);

            // Extra GC when navigating away, just to immediately clean up modlist metadata
            this.WhenAny(x => x.IsActive)
            .Where(x => !x)
            .Skip(1)
            .Delay(TimeSpan.FromMilliseconds(50), RxApp.MainThreadScheduler)
            .Subscribe(_ =>
            {
                GC.Collect();
            })
            .DisposeWith(CompositeDisposable);
        }
        public PlaylistViewModel()
        {
            this.Activator = new ViewModelActivator();
            this.entries   = new ReactiveList <PlaylistEntryViewModel>();
            this.currentTimeSecondsUserChanged = new Subject <int>();

            this.WhenActivated(() =>
            {
                var disposable = new CompositeDisposable();

                this.canModify = NetworkMessenger.Instance.WhenAnyValue(x => x.AccessPermission)
                                 .Select(x => x == NetworkAccessPermission.Admin)
                                 .ObserveOn(RxApp.MainThreadScheduler)
                                 .ToProperty(this, x => x.CanModify);
                this.canModify.DisposeWith(disposable);

                this.LoadPlaylistCommand = ReactiveCommand.CreateAsyncObservable(_ =>
                                                                                 NetworkMessenger.Instance.GetCurrentPlaylistAsync().ToObservable()
                                                                                 .Timeout(LoadPlaylistCommandTimeout, RxApp.TaskpoolScheduler)
                                                                                 .TakeUntil(disposable));

                var currentPlaylist = this.LoadPlaylistCommand
                                      .FirstAsync()
                                      .Concat(NetworkMessenger.Instance.PlaylistChanged.ObserveOn(RxApp.MainThreadScheduler))
                                      .Publish();
                currentPlaylist.Connect().DisposeWith(disposable);

                currentPlaylist.Select(x => x.Songs.Select((song, i) =>
                                                           new PlaylistEntryViewModel(song, x.CurrentIndex < i, x.CurrentIndex.HasValue && i == x.CurrentIndex)).ToList())
                .Subscribe(x =>
                {
                    using (this.entries.SuppressChangeNotifications())
                    {
                        this.entries.Clear();
                        this.entries.AddRange(x);
                    }
                });

                this.currentSong = this.entries.Changed.Select(x => this.entries.FirstOrDefault(y => y.IsPlaying))
                                   .ToProperty(this, x => x.CurrentSong);

                this.remainingVotes = NetworkMessenger.Instance.WhenAnyValue(x => x.GuestSystemInfo)
                                      .Select(x => x.IsEnabled ? new int?(x.RemainingVotes) : null)
                                      .ObserveOn(RxApp.MainThreadScheduler)
                                      .ToProperty(this, x => x.RemainingVotes)
                                      .DisposeWith(disposable);
                int?remainingVotesConnector = this.RemainingVotes;

                this.playbackState = currentPlaylist.Select(x => x.PlaybackState)
                                     .Merge(NetworkMessenger.Instance.PlaybackStateChanged.ObserveOn(RxApp.MainThreadScheduler))
                                     .ToProperty(this, x => x.PlaybackState)
                                     .DisposeWith(disposable);

                this.currentTimeSeconds = currentPlaylist.Select(x => x.CurrentTime)
                                          .Merge(NetworkMessenger.Instance.PlaybackTimeChanged)
                                          .Select(x => (int)x.TotalSeconds)
                                          .Select(x => Observable.Interval(TimeSpan.FromSeconds(1), RxApp.TaskpoolScheduler)
                                                  .Where(_ => this.IsPlaying)
                                                  .StartWith(x)
                                                  .Select((_, i) => x + i))
                                          .Switch()
                                          .ObserveOn(RxApp.MainThreadScheduler)
                                          .ToProperty(this, x => x.CurrentTimeSeconds)
                                          .DisposeWith(disposable);

                this.currentTimeSecondsUserChanged
                .Window(TimeThrottleDuration, TimeThrottleCount, RxApp.TaskpoolScheduler)
                .Select(x => x.DistinctUntilChanged())
                .Select(x => x.Take(1).Concat(x.Skip(1).TakeLast(1)))
                .Switch()
                .Select(x => TimeSpan.FromSeconds(x))
                .SelectMany(x => NetworkMessenger.Instance.SetCurrentTime(x).ToObservable().SwallowNetworkExceptions())
                .Subscribe()
                .DisposeWith(disposable);

                this.totalTime = currentPlaylist.Select(x => x.TotalTime)
                                 .ToProperty(this, x => x.TotalTime);

                var canVote = this.WhenAnyValue(x => x.CurrentSong, x => x.RemainingVotes, (currentSong, remainingVotes) =>
                                                currentSong != null && remainingVotes > 0);
                this.VoteCommand = ReactiveCommand.CreateAsyncObservable(canVote, _ =>
                                                                         NetworkMessenger.Instance.VoteAsync(this.SelectedEntry.Guid).ToObservable().TakeUntil(disposable));

                this.canVoteOnSelectedEntry = this.WhenAnyValue(x => x.SelectedEntry).Select(x => x != null && x.IsVoteAble)
                                              .CombineLatest(this.WhenAnyValue(x => x.RemainingVotes).Select(x => x.HasValue), (isVoteable, hasVotes) => isVoteable && hasVotes)
                                              .ToProperty(this, x => x.CanVoteOnSelectedEntry);
                var canVoteTemp = this.CanVoteOnSelectedEntry;

                this.PlayPlaylistSongCommand = ReactiveCommand.CreateAsyncObservable(this.WhenAnyValue(x => x.CanModify), _ =>
                                                                                     NetworkMessenger.Instance.PlayPlaylistSongAsync(this.SelectedEntry.Guid).ToObservable().TakeUntil(disposable));

                var canPlayNextSong = this.entries.Changed.Select(_ => this.entries)
                                      .StartWith(this.entries)
                                      .Select(x => x.Any(y => y.IsPlaying) && x.FirstOrDefault(y => y.IsPlaying) != x.LastOrDefault())
                                      .CombineLatest(this.WhenAnyValue(x => x.CanModify), (canPlayNext, canModify) => canPlayNext && canModify);
                this.PlayNextSongCommand = ReactiveCommand.CreateAsyncObservable(canPlayNextSong, _ =>
                                                                                 NetworkMessenger.Instance.PlayNextSongAsync().ToObservable().TakeUntil(disposable));

                var canPlayPreviousSong = this.entries.Changed.Select(_ => this.entries)
                                          .StartWith(this.entries)
                                          .Select(x => x.Any(y => y.IsPlaying) && x.FirstOrDefault(y => y.IsPlaying) != x.FirstOrDefault())
                                          .CombineLatest(this.WhenAnyValue(x => x.CanModify), (canPlayPrevious, canModify) => canPlayPrevious && canModify);
                this.PlayPreviousSongCommand = ReactiveCommand.CreateAsyncObservable(canPlayPreviousSong, _ =>
                                                                                     NetworkMessenger.Instance.PlayPreviousSongAsync().ToObservable().TakeUntil(disposable));

                this.isPlaying = this.WhenAnyValue(x => x.PlaybackState)
                                 .Select(x => x == NetworkPlaybackState.Playing)
                                 .ToProperty(this, x => x.IsPlaying);

                var canPlayOrPause = this.WhenAnyValue(x => x.PlaybackState)
                                     .Select(x => x == NetworkPlaybackState.Playing || x == NetworkPlaybackState.Paused)
                                     .CombineLatest(this.WhenAnyValue(x => x.CanModify), (canPlay, canModify) => canPlay && canModify);
                this.PlayPauseCommand = ReactiveCommand.CreateAsyncObservable(canPlayOrPause, _ =>
                {
                    if (this.IsPlaying)
                    {
                        return(NetworkMessenger.Instance.PauseSongAsync().ToObservable().TakeUntil(disposable));
                    }

                    return(NetworkMessenger.Instance.ContinueSongAsync().ToObservable().TakeUntil(disposable));
                });

                this.RemoveSongCommand = ReactiveCommand.CreateAsyncObservable(this.WhenAnyValue(x => x.CanModify), _ =>
                                                                               NetworkMessenger.Instance.RemovePlaylistSongAsync(this.SelectedEntry.Guid).ToObservable().TakeUntil(disposable));

                this.MoveSongDownCommand = ReactiveCommand.CreateAsyncObservable(this.WhenAnyValue(x => x.CanModify), _ =>
                                                                                 NetworkMessenger.Instance.MovePlaylistSongDownAsync(this.SelectedEntry.Guid).ToObservable().TakeUntil(disposable));

                this.MoveSongUpCommand = ReactiveCommand.CreateAsyncObservable(this.WhenAnyValue(x => x.CanModify), _ =>
                                                                               NetworkMessenger.Instance.MovePlaylistSongUpAsync(this.SelectedEntry.Guid).ToObservable().TakeUntil(disposable));

                this.ToggleVideoPlayerCommand = ReactiveCommand.CreateAsyncObservable(this.WhenAnyValue(x => x.CanModify), _ =>
                                                                                      NetworkMessenger.Instance.ToggleVideoPlayer().ToObservable().TakeUntil(disposable));

                return(disposable);
            });
        }
Esempio n. 44
0
        public SubordinateViewModel(IMainViewModel mainWindowViewModel) : base(nameof(SubordinateViewModel), mainWindowViewModel)
        {
            SetNotification("Loading subordinate data", NotificationType.Refreshing);

            _mainWindowViewModel = mainWindowViewModel;

            SearchText = string.Empty;

            _networkServiceOfPersons ??= Locator.Current.GetService <INetworkService <Person> >();
            _networkServiceOfFileData ??= Locator.Current.GetService <INetworkService <FileData> >();
            _settingsService ??= Locator.Current.GetService <ISettingsService>();

            #region Init Chat service
            _clientService ??= Locator.Current.GetService <IClientService>();
            _clientService.MessageReceived += MessageReceived;
            #endregion

            #region Init SelectPersonCommand
            SelectPersonCommand = ReactiveCommand.CreateFromTask <Person, bool>(SelectPersonExecutedAsync);
            SelectPersonCommand.ThrownExceptions.Subscribe(exception =>
            {
                IsPhotoLoading = false;
                ErrorHandler(nameof(SelectPersonCommand)).Invoke(exception);
            });
            this.WhenAnyValue(x => x.SelectedPerson).InvokeCommand(SelectPersonCommand);
            #endregion

            #region Init SearchPersonCommand
            var canSearch = this.WhenAnyValue(x => x.SearchText, query => !string.IsNullOrWhiteSpace(query));
            SearchPersonCommand =
                ReactiveCommand.CreateFromTask <string, IEnumerable <Person> >(
                    async query => await SearchPersonExecuteAsync(query),
                    canSearch);
            SearchPersonCommand.IsExecuting.ToProperty(this, x => x.IsSearching, out _isSearching);
            SearchPersonCommand.ThrownExceptions.Subscribe(ErrorHandler(nameof(SearchPersonCommand)));
            _searchedPersons = SearchPersonCommand.ToProperty(this, x => x.Persons);

            this.WhenAnyValue(x => x.SearchText)
            .Throttle(TimeSpan.FromSeconds(1), RxApp.MainThreadScheduler)
            .InvokeCommand(SearchPersonCommand);
            #endregion

            #region Init ClearSearchPersonCommand
            var canClearSearch = this.WhenAnyValue(x => x.SearchText, query => !string.IsNullOrWhiteSpace(query) || Persons.Any());
            ClearSearchPersonCommand = ReactiveCommand.CreateFromTask <Unit, bool>(ClearSearchPersonsAsync, canClearSearch);
            ClearSearchPersonCommand.ThrownExceptions.Subscribe(ErrorHandler(nameof(ClearSearchPersonCommand)));
            #endregion

            #region Init SendPersonCommand
            var canSendPerson =
                this.WhenAnyValue(
                    x => x.IsLoading,
                    x => x.Visitor.Comment,
                    x => x.Visitor.FirstName,
                    x => x.Visitor.Message,
                    x => x.Visitor.MiddleName,
                    x => x.Visitor.Post,
                    x => x.Visitor.SecondName,
                    selector: (isLoading, _, __, ___, ____, _____, ______) => !Visitor.IsNullOrEmpty() && !isLoading);
            SendVisitorCommand = ReactiveCommand.CreateFromTask <Visitor, bool>(SendVisitorExecuteAsync, canSendPerson);
            SendVisitorCommand.ThrownExceptions.Subscribe(ErrorHandler(nameof(SendVisitorCommand)));
            #endregion

            Initialized += OnSubordinateViewModelInitialized;
            OnInitialized();
        }
Esempio n. 45
0
        public MO2InstallerVM(InstallerVM installerVM)
        {
            Parent = installerVM;

            Location = new FilePickerVM()
            {
                ExistCheckOption = FilePickerVM.CheckOptions.Off,
                PathType         = FilePickerVM.PathTypeOptions.Folder,
                PromptTitle      = "Select Installation Directory",
            };
            DownloadLocation = new FilePickerVM()
            {
                ExistCheckOption = FilePickerVM.CheckOptions.Off,
                PathType         = FilePickerVM.PathTypeOptions.Folder,
                PromptTitle      = "Select a location for MO2 downloads",
            };
            DownloadLocation.AdditionalError = this.WhenAny(x => x.DownloadLocation.TargetPath)
                                               .Select(x => Utils.IsDirectoryPathValid(x));
            Location.AdditionalError = Observable.CombineLatest(
                this.WhenAny(x => x.Location.TargetPath),
                this.WhenAny(x => x.DownloadLocation.TargetPath),
                resultSelector: (target, download) => (target, download))
                                       .ObserveOn(RxApp.TaskpoolScheduler)
                                       .Select(i => MO2Installer.CheckValidInstallPath(i.target, i.download))
                                       .ObserveOnGuiThread();

            CanInstall = Observable.CombineLatest(
                this.WhenAny(x => x.Location.InError),
                this.WhenAny(x => x.DownloadLocation.InError),
                installerVM.WhenAny(x => x.ModListLocation.InError),
                resultSelector: (loc, modlist, download) =>
            {
                return(!loc && !download && !modlist);
            });

            // Have Installation location updates modify the downloads location if empty
            this.WhenAny(x => x.Location.TargetPath)
            .Skip(1)     // Don't do it initially
            .Subscribe(installPath =>
            {
                if (DownloadLocation.TargetPath == default)
                {
                    DownloadLocation.TargetPath = installPath.Combine("downloads");
                }
            })
            .DisposeWith(CompositeDisposable);

            // Load settings
            _CurrentSettings = installerVM.WhenAny(x => x.ModListLocation.TargetPath)
                               .Select(path => path == null ? null : installerVM.MWVM.Settings.Installer.Mo2ModlistSettings.TryCreate(path))
                               .ToGuiProperty(this, nameof(CurrentSettings));
            this.WhenAny(x => x.CurrentSettings)
            .Pairwise()
            .Subscribe(settingsPair =>
            {
                SaveSettings(settingsPair.Previous);
                if (settingsPair.Current == null)
                {
                    return;
                }
                Location.TargetPath         = settingsPair.Current.InstallationLocation;
                DownloadLocation.TargetPath = settingsPair.Current.DownloadLocation;
                AutomaticallyOverwrite      = settingsPair.Current.AutomaticallyOverrideExistingInstall;
            })
            .DisposeWith(CompositeDisposable);
            installerVM.MWVM.Settings.SaveSignal
            .Subscribe(_ => SaveSettings(CurrentSettings))
            .DisposeWith(CompositeDisposable);

            // Hook onto user interventions, and intercept MO2 specific ones for customization
            this.WhenAny(x => x.ActiveInstallation)
            .Select(x => x?.LogMessages ?? Observable.Empty <IStatusMessage>())
            .Switch()
            .Subscribe(x =>
            {
                switch (x)
                {
                case ConfirmUpdateOfExistingInstall c:
                    if (AutomaticallyOverwrite)
                    {
                        c.Confirm();
                    }
                    break;

                default:
                    break;
                }
            })
            .DisposeWith(CompositeDisposable);
        }
Esempio n. 46
0
        public NuGetPackageDetailViewModel()
        {
            GetVersions = ReactiveCommand.CreateFromTask <IPackageSearchMetadata, IEnumerable <NuGetVersionViewModel> >(ExecuteGetVersions);

            _versions = GetVersions.ToProperty(this, x => x.Versions, scheduler: RxApp.MainThreadScheduler);
        }
Esempio n. 47
0
        public PullRequestViewModel(
            IApplicationService applicationService,
            IMarkdownService markdownService,
            IActionMenuFactory actionMenuService)
            : base(applicationService, markdownService)
        {
            this.WhenAnyValue(x => x.Id)
            .Subscribe(x => Title = "Pull Request #" + x);

            _canMerge = this.WhenAnyValue(x => x.PullRequest)
                        .Select(x => x != null && !x.Merged)
                        .ToProperty(this, x => x.CanMerge);

            var canMergeObservable = this.WhenAnyValue(x => x.PullRequest).Select(x =>
                                                                                  x != null && !x.Merged && x.Mergeable.HasValue && x.Mergeable.Value);

            MergeCommand = ReactiveCommand.CreateAsyncTask(canMergeObservable, async t =>
            {
                var req      = new Octokit.MergePullRequest(null);
                var response = await applicationService.GitHubClient.PullRequest.Merge(RepositoryOwner, RepositoryName, Id, req);
                if (!response.Merged)
                {
                    throw new Exception(string.Format("Unable to merge pull request: {0}", response.Message));
                }
                LoadCommand.ExecuteIfCan();
            });

//            ToggleStateCommand = ReactiveCommand.CreateAsyncTask(
//                this.WhenAnyValue(x => x.PullRequest).Select(x => x != null),
//                async t =>
//            {
//                var newState = PullRequest.State == Octokit.ItemState.Open ? Octokit.ItemState.Closed : Octokit.ItemState.Open;
//
//                try
//                {
//                    var req = new Octokit.PullRequestUpdate { State = newState };
//                    PullRequest = await applicationService.GitHubClient.PullRequest.Update(RepositoryOwner, RepositoryName, Id, req);
//                }
//                catch (Exception e)
//                {
//                    throw new Exception("Unable to " + (newState == Octokit.ItemState.Closed ? "close" : "open") + " the item. " + e.Message, e);
//                }
//            });


            GoToHtmlUrlCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.PullRequest).Select(x => x != null));
            GoToHtmlUrlCommand.Select(_ => PullRequest.HtmlUrl).Subscribe(GoToUrlCommand.ExecuteIfCan);

            GoToCommitsCommand = ReactiveCommand.Create().WithSubscription(_ =>
            {
                var vm             = this.CreateViewModel <PullRequestCommitsViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName  = RepositoryName;
                vm.PullRequestId   = Id;
                NavigateTo(vm);
            });

            GoToFilesCommand = ReactiveCommand.Create().WithSubscription(_ =>
            {
                var vm             = this.CreateViewModel <PullRequestFilesViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName  = RepositoryName;
                vm.PullRequestId   = Id;
                NavigateTo(vm);
            });

            ShareCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.PullRequest).Select(x => x != null));
            ShareCommand.Subscribe(_ => actionMenuService.ShareUrl(PullRequest.HtmlUrl));

            GoToEditCommand = ReactiveCommand.Create().WithSubscription(_ =>
            {
                var vm             = this.CreateViewModel <IssueEditViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName  = RepositoryName;
                vm.Id = Id;
                //vm.Issue = Issue;
//                vm.WhenAnyValue(x => x.Issue).Skip(1).Subscribe(x => Issue = x);
                NavigateTo(vm);
            });

            ShowMenuCommand = ReactiveCommand.CreateAsyncTask(
                this.WhenAnyValue(x => x.PullRequest).Select(x => x != null),
                _ =>
            {
                var menu = actionMenuService.Create(Title);
                menu.AddButton("Edit", GoToEditCommand);
                menu.AddButton(PullRequest.State == Octokit.ItemState.Closed ? "Open" : "Close", ToggleStateCommand);
                menu.AddButton("Comment", GoToAddCommentCommand);
                menu.AddButton("Share", ShareCommand);
                menu.AddButton("Show in GitHub", GoToHtmlUrlCommand);
                return(menu.Show());
            });
        }
        public async Task InitializeAsync(ILocalRepositoryModel repository, IConnection connection)
        {
            modelService = await modelServiceFactory.CreateAsync(connection);

            activeLocalRepo = repository;
            SourceBranch    = repository.CurrentBranch;

            var obs = modelService.ApiClient.GetRepository(repository.Owner, repository.Name)
                      .Select(r => new RemoteRepositoryModel(r))
                      .PublishLast();

            disposables.Add(obs.Connect());
            var githubObs = obs;

            githubRepository = githubObs.ToProperty(this, x => x.GitHubRepository);

            this.WhenAnyValue(x => x.GitHubRepository)
            .WhereNotNull()
            .Subscribe(r =>
            {
                TargetBranch = r.IsFork ? r.Parent.DefaultBranch : r.DefaultBranch;
            });

            githubObs.SelectMany(r =>
            {
                var b = Observable.Empty <IBranch>();
                if (r.IsFork)
                {
                    b = modelService.GetBranches(r.Parent).Select(x =>
                    {
                        return(x);
                    });
                }
                return(b.Concat(modelService.GetBranches(r)));
            })
            .ToList()
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(x =>
            {
                Branches    = x.ToList();
                Initialized = true;
            });

            SourceBranch = activeLocalRepo.CurrentBranch;

            var uniqueCommits = this.WhenAnyValue(
                x => x.SourceBranch,
                x => x.TargetBranch)
                                .Where(x => x.Item1 != null && x.Item2 != null)
                                .Select(branches =>
            {
                var baseBranch    = branches.Item1.Name;
                var compareBranch = branches.Item2.Name;

                // We only need to get max two commits for what we're trying to achieve here.
                // If there's no commits we want to block creation of the PR, if there's one commits
                // we wan't to use its commit message as the PR title/body and finally if there's more
                // than one we'll use the branch name for the title.
                return(service.GetMessagesForUniqueCommits(activeLocalRepo, baseBranch, compareBranch, maxCommits: 2)
                       .Catch <IReadOnlyList <CommitMessage>, Exception>(ex =>
                {
                    log.Warning(ex, "Could not load unique commits");
                    return Observable.Empty <IReadOnlyList <CommitMessage> >();
                }));
            })
                                .Switch()
                                .ObserveOn(RxApp.MainThreadScheduler)
                                .Replay(1)
                                .RefCount();

            Observable.CombineLatest(
                this.WhenAnyValue(x => x.SourceBranch),
                uniqueCommits,
                service.GetPullRequestTemplate(repository).DefaultIfEmpty(string.Empty),
                (compare, commits, template) => new { compare, commits, template })
            .Subscribe(x =>
            {
                var prTitle       = string.Empty;
                var prDescription = string.Empty;

                if (x.commits.Count == 1)
                {
                    prTitle       = x.commits[0].Summary;
                    prDescription = x.commits[0].Details;
                }
                else
                {
                    prTitle = x.compare.Name.Humanize();
                }

                if (!string.IsNullOrWhiteSpace(x.template))
                {
                    if (!string.IsNullOrEmpty(prDescription))
                    {
                        prDescription += "\n\n";
                    }
                    prDescription += x.template;
                }

                PRTitle     = prTitle;
                Description = prDescription;
            });

            Initialized = true;
        }
Esempio n. 49
0
    public CloudViewModel(
        CloudState state,
        CreateFolderViewModelFactory createFolderFactory,
        RenameFileViewModelFactory renameFactory,
        FileViewModelFactory fileFactory,
        FolderViewModelFactory folderFactory,
        IAuthViewModel auth,
        IFileManager files,
        ICloud cloud)
    {
        _cloud = cloud;
        Folder = createFolderFactory(this);
        Rename = renameFactory(this);
        Auth   = auth;

        var canInteract = this
                          .WhenAnyValue(
            x => x.Folder.IsVisible,
            x => x.Rename.IsVisible,
            (folder, rename) => !folder && !rename);

        _canInteract = canInteract
                       .ToProperty(this, x => x.CanInteract);

        var canRefresh = this
                         .WhenAnyValue(
            x => x.Folder.IsVisible,
            x => x.Rename.IsVisible,
            x => x.Auth.IsAuthenticated,
            (folder, rename, authenticated) => !folder && !rename && authenticated);

        Refresh = ReactiveCommand.CreateFromTask(
            () => cloud.GetFiles(CurrentPath),
            canRefresh);

        _files = Refresh
                 .Select(
            items => items
            .Select(file => fileFactory(file, this))
            .OrderByDescending(file => file.IsFolder)
            .ThenBy(file => file.Name)
            .ToList())
                 .Where(items => Files == null || !items.SequenceEqual(Files))
                 .ToProperty(this, x => x.Files);

        _isLoading = Refresh
                     .IsExecuting
                     .ToProperty(this, x => x.IsLoading);

        _isReady = Refresh
                   .IsExecuting
                   .Skip(1)
                   .Select(executing => !executing)
                   .ToProperty(this, x => x.IsReady);

        var canOpenCurrentPath = this
                                 .WhenAnyValue(x => x.SelectedFile)
                                 .Select(file => file != null && file.IsFolder)
                                 .CombineLatest(Refresh.IsExecuting, canInteract, (folder, busy, ci) => folder && ci && !busy);

        Open = ReactiveCommand.Create(
            () => Path.Combine(CurrentPath, SelectedFile.Name),
            canOpenCurrentPath);

        var canCurrentPathGoBack = this
                                   .WhenAnyValue(x => x.CurrentPath)
                                   .Where(path => path != null)
                                   .Select(path => path.Length > cloud.InitialPath.Length)
                                   .CombineLatest(Refresh.IsExecuting, canInteract, (valid, busy, ci) => valid && ci && !busy);

        Back = ReactiveCommand.Create(
            () => Path.GetDirectoryName(CurrentPath),
            canCurrentPathGoBack);

        SetPath = ReactiveCommand.Create <string, string>(path => path);

        _currentPath = Open
                       .Merge(Back)
                       .Merge(SetPath)
                       .Select(path => path ?? cloud.InitialPath)
                       .DistinctUntilChanged()
                       .Log(this, $"Current path changed in {cloud.Name}")
                       .ToProperty(this, x => x.CurrentPath, state.CurrentPath ?? cloud.InitialPath);

        var getBreadCrumbs = ReactiveCommand.CreateFromTask(
            () => cloud.GetBreadCrumbs(CurrentPath));

        _breadCrumbs = getBreadCrumbs
                       .Where(items => items != null && items.Any())
                       .Select(items => items.Select(folder => folderFactory(folder, this)))
                       .ToProperty(this, x => x.BreadCrumbs);

        _showBreadCrumbs = getBreadCrumbs
                           .ThrownExceptions
                           .Select(exception => false)
                           .Merge(getBreadCrumbs.Select(items => items != null && items.Any()))
                           .ObserveOn(RxApp.MainThreadScheduler)
                           .ToProperty(this, x => x.ShowBreadCrumbs);

        _hideBreadCrumbs = this
                           .WhenAnyValue(x => x.ShowBreadCrumbs)
                           .Select(show => !show)
                           .ToProperty(this, x => x.HideBreadCrumbs);

        this.WhenAnyValue(x => x.CurrentPath, x => x.IsReady)
        .Where(x => x.Item1 != null && x.Item2)
        .Select(_ => Unit.Default)
        .InvokeCommand(getBreadCrumbs);

        this.WhenAnyValue(x => x.CurrentPath)
        .Skip(1)
        .Select(_ => Unit.Default)
        .InvokeCommand(Refresh);

        this.WhenAnyValue(x => x.CurrentPath)
        .Subscribe(_ => SelectedFile = null);

        _isCurrentPathEmpty = this
                              .WhenAnyValue(x => x.Files)
                              .Skip(1)
                              .Where(items => items != null)
                              .Select(items => !items.Any())
                              .ToProperty(this, x => x.IsCurrentPathEmpty);

        _hasErrorMessage = Refresh
                           .ThrownExceptions
                           .Select(exception => true)
                           .ObserveOn(RxApp.MainThreadScheduler)
                           .Merge(Refresh.Select(x => false))
                           .ToProperty(this, x => x.HasErrorMessage);

        var canUploadToCurrentPath = this
                                     .WhenAnyValue(x => x.CurrentPath)
                                     .Select(path => path != null)
                                     .CombineLatest(Refresh.IsExecuting, canInteract, (up, loading, can) => up && can && !loading);

        UploadToCurrentPath = ReactiveCommand.CreateFromObservable(
            () => Observable
            .FromAsync(files.OpenRead)
            .Where(response => response.Name != null && response.Stream != null)
            .Select(args => _cloud.UploadFile(CurrentPath, args.Stream, args.Name))
            .SelectMany(task => task.ToObservable()),
            canUploadToCurrentPath);

        UploadToCurrentPath.InvokeCommand(Refresh);

        var canDownloadSelectedFile = this
                                      .WhenAnyValue(x => x.SelectedFile)
                                      .Select(file => file != null && !file.IsFolder)
                                      .CombineLatest(Refresh.IsExecuting, canInteract, (down, loading, can) => down && !loading && can);

        DownloadSelectedFile = ReactiveCommand.CreateFromObservable(
            () => Observable
            .FromAsync(() => files.OpenWrite(SelectedFile.Name))
            .Where(stream => stream != null)
            .Select(stream => _cloud.DownloadFile(SelectedFile.Path, stream))
            .SelectMany(task => task.ToObservable()),
            canDownloadSelectedFile);

        var canLogout = cloud
                        .IsAuthorized
                        .DistinctUntilChanged()
                        .Select(loggedIn => loggedIn && (
                                    cloud.SupportsDirectAuth ||
                                    cloud.SupportsOAuth ||
                                    cloud.SupportsHostAuth))
                        .CombineLatest(canInteract, (logout, interact) => logout && interact)
                        .ObserveOn(RxApp.MainThreadScheduler);

        Logout = ReactiveCommand.CreateFromTask(cloud.Logout, canLogout);

        _canLogout = canLogout
                     .ToProperty(this, x => x.CanLogout);

        var canDeleteSelection = this
                                 .WhenAnyValue(x => x.SelectedFile)
                                 .Select(file => file != null && !file.IsFolder)
                                 .CombineLatest(Refresh.IsExecuting, canInteract, (del, loading, ci) => del && !loading && ci);

        DeleteSelectedFile = ReactiveCommand.CreateFromTask(
            () => cloud.Delete(SelectedFile.Path, SelectedFile.IsFolder),
            canDeleteSelection);

        DeleteSelectedFile.InvokeCommand(Refresh);

        var canUnselectFile = this
                              .WhenAnyValue(x => x.SelectedFile)
                              .Select(selection => selection != null)
                              .CombineLatest(Refresh.IsExecuting, canInteract, (sel, loading, ci) => sel && !loading && ci);

        UnselectFile = ReactiveCommand.Create(
            () => { SelectedFile = null; },
            canUnselectFile);

        UploadToCurrentPath.ThrownExceptions
        .Merge(DeleteSelectedFile.ThrownExceptions)
        .Merge(DownloadSelectedFile.ThrownExceptions)
        .Merge(Refresh.ThrownExceptions)
        .Merge(getBreadCrumbs.ThrownExceptions)
        .Log(this, $"Exception occured in provider {cloud.Name}")
        .Subscribe();

        this.WhenAnyValue(x => x.CurrentPath)
        .Subscribe(path => state.CurrentPath = path);

        this.WhenAnyValue(x => x.Auth.IsAuthenticated)
        .Select(authenticated => authenticated ? _cloud.Parameters?.Token : null)
        .Subscribe(token => state.Token = token);

        this.WhenAnyValue(x => x.Auth.IsAuthenticated)
        .Select(authenticated => authenticated ? _cloud.Parameters?.User : null)
        .Subscribe(user => state.User = user);

        this.WhenActivated(ActivateAutoRefresh);
    }
Esempio n. 50
0
        public ItemEditorViewModel(
            IManualTagEditor tagEdiotr,
            IItemService itemService,
            FileVersionListViewModel fileVersionList,
            INotificationCenterService notificationCenter,
            ILibraryManagementService libraryManagement,
            IFileItemLinkService fileItemLinkService,
            OpenFileCommand openFile,
            FileToClipboardCommand fileToClipboard,
            ISettingsService settingsService,
            IThumbnailManagementService thumbnailManagementService)
        {
            this.TagEditor           = tagEdiotr;
            this._itemService        = itemService;
            FileVersionList          = fileVersionList;
            this.notificationCenter  = notificationCenter;
            this.libraryManagement   = libraryManagement;
            this.fileItemLinkService = fileItemLinkService;
            OpenFile        = openFile;
            FileToClipboard = fileToClipboard;
            this.thumbnailManagementService = thumbnailManagementService;
            this.TagEditor.Editmode         = true;
            this.TagEditor.CompletePool     = true;
            this.TagEditor.PermitNewTags    = true;
            this.disposables.Add(_selectedItemIdChanges);

            this.SelectedItemChanges =
                this._itemService
                .GetExtended(this.SelectedItemIdChanges)
                .TakeUntil(destroy);

            this.Save            = new RelayCommand(_ => _save());
            this.CreateThumbnail = new RelayCommand(_ => createThumbnail());

            var selectedVersionChanges = this.WhenAnyValue(x => x.SelectedVersion).TakeUntil(destroy);

            var curLink = this.newLinks.Connect()
                          .ChangeKey(link => link.Version)
                          .WatchValue(selectedVersionChanges, link => link.Version);

            var curFileFilter =
                selectedVersionChanges.CombineLatest(SelectedItemChanges, (version, item) => new { version, item })
                .Select(
                    x =>
            {
                return(new Func <VersionedFile, bool>((VersionedFile vFile)
                                                      => x.version.HasValue && x.item.HasValue && (vFile.Version == x.version.Value) && (vFile.ItemId == x.item.Value.ItemId)));
            });

            var files = this.fileItemLinkService.BuildversionedFiles(newLinks.Connect());

            var curFiles = files.Filter(curFileFilter)
                           .Select(x => x.FirstOrDefault(x => x.Reason != ChangeReason.Remove).Current.ToNullable());

            this._selectedFiles = curFiles
                                  .TakeUntil(destroy)
                                  .ToProperty(this, nameof(SelectedFiles));

            this._cameraRotationMode = settingsService
                                       .WhenAnyValue(x => x.CameraRotationMode)
                                       .Select(x => (CameraRotationMode)x)
                                       .ToProperty(this, nameof(CameraRotationMode));
            _cameraRotationMode.DisposeWith(disposables);

            DateTime mostRecentRequest = default;

            curFiles
            .ObserveOn(RxApp.TaskpoolScheduler)
            .TakeUntil(destroy)
            .Select(files =>
            {
                mostRecentRequest = DateTime.Now;
                var orderTime     = DateTime.Now;
                if (!files.HasValue || files?.File.AbsolutePath == null)
                {
                    return(null);
                }
                this.MaterialBrush     = new SolidColorBrush(Colors.LightGray);
                var mat                = new DiffuseMaterial(this.MaterialBrush);
                ModelImporter importer = new ModelImporter()
                {
                    DefaultMaterial = mat
                };
                Model3DGroup model = importer.Load(files.Value.File.AbsolutePath);
                model.SetMaterial(mat);
                model.PlaceAtOrigin();
                model.Freeze();
                return(new { timestamp = mostRecentRequest, model });
            })
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(x =>
            {
                this.ViewportContent = null;
                if (x == null)
                {
                    return;
                }
                LoadingModel = true;
                RxApp.MainThreadScheduler.Schedule(x.model, (_, model) =>
                {
                    if (x.timestamp == mostRecentRequest)
                    {
                        this.ViewportContent = model;
                        LoadingModel         = false;
                    }
                    return(null);
                });
            });

            var linkFilter = selectedVersionChanges.Select(version =>
                                                           new Func <FileItemLink, bool>(link => link.Version == version)
                                                           );

            var selectedLinkChanges = this.newLinks
                                      .Connect()
                                      .RemoveKey()
                                      .Filter(linkFilter)
                                      .Select(x => x.FirstOrDefault().Item.Current);



            this.SelectedItemChanges.Subscribe(
                LoadItem,
                ex => this.notificationCenter.OnError(ex));
        }
Esempio n. 51
0
        public void SubscribeEvents()
        {
            lock (DisposablesLock)
            {
                if (Disposables != null)
                {
                    throw new Exception("Please report to Dan");
                }

                Disposables = new CompositeDisposable();

                //TODO defer subscription to when accessed (will be faster in ui.)
                _coinJoinInProgress = Model.WhenAnyValue(x => x.CoinJoinInProgress)
                                      .ToProperty(this, x => x.CoinJoinInProgress, scheduler: RxApp.MainThreadScheduler)
                                      .DisposeWith(Disposables);

                _unspent = Model.WhenAnyValue(x => x.Unspent)
                           .ToProperty(this, x => x.Unspent, scheduler: RxApp.MainThreadScheduler)
                           .DisposeWith(Disposables);

                _confirmed = Model.WhenAnyValue(x => x.Confirmed)
                             .ToProperty(this, x => x.Confirmed, scheduler: RxApp.MainThreadScheduler)
                             .DisposeWith(Disposables);

                _unavailable = Model.WhenAnyValue(x => x.Unavailable)
                               .ToProperty(this, x => x.Unavailable, scheduler: RxApp.MainThreadScheduler)
                               .DisposeWith(Disposables);

                this.WhenAnyValue(x => x.Status)
                .Subscribe(_ => this.RaisePropertyChanged(nameof(ToolTip)));

                this.WhenAnyValue(x => x.Confirmed, x => x.CoinJoinInProgress, x => x.Confirmations)
                .ObserveOn(RxApp.MainThreadScheduler)
                .Subscribe(_ => RefreshSmartCoinStatus());

                this.WhenAnyValue(x => x.IsSelected)
                .ObserveOn(RxApp.MainThreadScheduler)
                .Subscribe(_ => _owner.OnCoinIsSelectedChanged(this));

                this.WhenAnyValue(x => x.Status)
                .ObserveOn(RxApp.MainThreadScheduler)
                .Subscribe(_ => _owner.OnCoinStatusChanged());

                this.WhenAnyValue(x => x.Unspent)
                .ObserveOn(RxApp.MainThreadScheduler)
                .Subscribe(_ => _owner.OnCoinUnspentChanged(this));

                Model.WhenAnyValue(x => x.IsBanned, x => x.SpentAccordingToBackend)
                .ObserveOn(RxApp.MainThreadScheduler)
                .Subscribe(_ => RefreshSmartCoinStatus())
                .DisposeWith(Disposables);

                Observable.FromEventPattern(
                    Global.ChaumianClient,
                    nameof(Global.ChaumianClient.StateUpdated))
                .ObserveOn(RxApp.MainThreadScheduler)
                .Subscribe(_ => RefreshSmartCoinStatus())
                .DisposeWith(Disposables);

                Global.BitcoinStore.HashChain.WhenAnyValue(x => x.ServerTipHeight)
                .ObserveOn(RxApp.MainThreadScheduler)
                .Subscribe(_ => this.RaisePropertyChanged(nameof(Confirmations)))
                .DisposeWith(Disposables);

                Global.UiConfig.WhenAnyValue(x => x.LurkingWifeMode)
                .ObserveOn(RxApp.MainThreadScheduler)
                .Subscribe(_ =>
                {
                    this.RaisePropertyChanged(nameof(AmountBtc));
                    this.RaisePropertyChanged(nameof(Clusters));
                }).DisposeWith(Disposables);
            }
        }
Esempio n. 52
0
        public IssueViewModel(IApplicationService applicationService, IActionMenuFactory actionMenuFactory,
                              IMarkdownService markdownService, IGraphicService graphicsService)
        {
            _applicationService = applicationService;

            var issuePresenceObservable = this.WhenAnyValue(x => x.Issue).Select(x => x != null);

            GoToAssigneesCommand = ReactiveCommand.Create(issuePresenceObservable)
                                   .WithSubscription(_ => Assignees.LoadCommand.ExecuteIfCan());

            GoToLabelsCommand = ReactiveCommand.Create(issuePresenceObservable)
                                .WithSubscription(_ => Labels.LoadCommand.ExecuteIfCan());

            GoToMilestonesCommand = ReactiveCommand.Create(issuePresenceObservable)
                                    .WithSubscription(_ => Milestones.LoadCommand.ExecuteIfCan());

            this.WhenAnyValue(x => x.Id)
            .Subscribe(x => Title = "Issue #" + x);

            _assignedUser = this.WhenAnyValue(x => x.Issue.Assignee)
                            .ToProperty(this, x => x.AssignedUser);

            _assignedMilestone = this.WhenAnyValue(x => x.Issue.Milestone)
                                 .ToProperty(this, x => x.AssignedMilestone);

            _assignedLabels = this.WhenAnyValue(x => x.Issue.Labels)
                              .ToProperty(this, x => x.AssignedLabels);

            _markdownDescription = this.WhenAnyValue(x => x.Issue)
                                   .Select(x => ((x == null || string.IsNullOrEmpty(x.Body)) ? null : markdownService.Convert(x.Body)))
                                   .ToProperty(this, x => x.MarkdownDescription);

            ShareCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.Issue).Select(x => x != null));
            ShareCommand.Subscribe(_ => actionMenuFactory.ShareUrl(Issue.HtmlUrl));

            var events = new ReactiveList <IIssueEventItemViewModel>();

            Events = events.CreateDerivedCollection(x => x);

            AddCommentCommand = ReactiveCommand.Create();
            AddCommentCommand.Subscribe(_ =>
            {
                var vm             = this.CreateViewModel <IssueCommentViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName  = RepositoryName;
                vm.Id = Id;
                vm.SaveCommand.Subscribe(x => events.Add(new IssueCommentItemViewModel(x)));
                NavigateTo(vm);
            });

            ToggleStateCommand = ReactiveCommand.CreateAsyncTask(issuePresenceObservable, async t =>
            {
                try
                {
                    Issue = await applicationService.GitHubClient.Issue.Update(RepositoryOwner, RepositoryName, Id, new Octokit.IssueUpdate {
                        State = (Issue.State == Octokit.ItemState.Open) ? Octokit.ItemState.Closed : Octokit.ItemState.Open
                    });
                }
                catch (Exception e)
                {
                    var close = (Issue.State == Octokit.ItemState.Open) ? "close" : "open";
                    throw new Exception("Unable to " + close + " the item. " + e.Message, e);
                }
            });

            GoToEditCommand = ReactiveCommand.Create(issuePresenceObservable);
            GoToEditCommand.Subscribe(_ =>
            {
                var vm             = this.CreateViewModel <IssueEditViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName  = RepositoryName;
                vm.Id = Id;
//                vm.Issue = Issue;
//                vm.WhenAnyValue(x => x.Issue).Skip(1).Subscribe(x => Issue = x);
                NavigateTo(vm);
            });

            Assignees = new IssueAssigneeViewModel(
                () => applicationService.GitHubClient.Issue.Assignee.GetForRepository(RepositoryOwner, RepositoryName),
                () => Task.FromResult(Issue),
                UpdateIssue);

            Milestones = new IssueMilestonesViewModel(
                () => applicationService.GitHubClient.Issue.Milestone.GetForRepository(RepositoryOwner, RepositoryName),
                () => Task.FromResult(Issue),
                UpdateIssue);

            Labels = new IssueLabelsViewModel(
                () => applicationService.GitHubClient.Issue.Labels.GetForRepository(RepositoryOwner, RepositoryName),
                () => Task.FromResult(Issue),
                UpdateIssue,
                graphicsService);

            LoadCommand = ReactiveCommand.CreateAsyncTask(async t =>
            {
                var issueRequest = applicationService.GitHubClient.Issue.Get(RepositoryOwner, RepositoryName, Id)
                                   .ContinueWith(x => Issue = x.Result, new CancellationToken(), TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.FromCurrentSynchronizationContext());
                var eventsRequest   = applicationService.GitHubClient.Issue.Events.GetForIssue(RepositoryOwner, RepositoryName, Id);
                var commentsRequest = applicationService.GitHubClient.Issue.Comment.GetForIssue(RepositoryOwner, RepositoryName, Id);
                await Task.WhenAll(issueRequest, eventsRequest, commentsRequest);

                var tempList = new List <IIssueEventItemViewModel>(eventsRequest.Result.Count + commentsRequest.Result.Count);
                tempList.AddRange(eventsRequest.Result.Select(x => new IssueEventItemViewModel(x)));
                tempList.AddRange(commentsRequest.Result.Select(x => new IssueCommentItemViewModel(x)));
                events.Reset(tempList.OrderBy(x => x.CreatedAt));
            });

            ShowMenuCommand = ReactiveCommand.CreateAsyncTask(
                this.WhenAnyValue(x => x.Issue).Select(x => x != null),
                _ =>
            {
                var menu = actionMenuFactory.Create(Title);
                menu.AddButton(Issue.State == Octokit.ItemState.Open ? "Close" : "Open", ToggleStateCommand);
//
//
//                var editButton = _actionSheet.AddButton("Edit");
//                var commentButton = _actionSheet.AddButton("Comment");
//                var shareButton = _actionSheet.AddButton("Share");
//                var showButton = _actionSheet.AddButton("Show in GitHub");

                return(menu.Show());
            });
        }
Esempio n. 53
0
        public ModListMetadataVM(ModListGalleryVM parent, ModlistMetadata metadata)
        {
            _parent        = parent;
            Metadata       = metadata;
            Location       = Consts.ModListDownloadFolder.Combine(Metadata.Links.MachineURL + (string)Consts.ModListExtension);
            ModListTagList = new List <ModListTag>();
            Metadata.tags.ForEach(tag =>
            {
                ModListTagList.Add(new ModListTag(tag));
            });
            DownloadSizeText   = "Download size : " + UIUtils.FormatBytes(Metadata.DownloadMetadata.SizeOfArchives);
            InstallSizeText    = "Installation size : " + UIUtils.FormatBytes(Metadata.DownloadMetadata.SizeOfInstalledFiles);
            IsBroken           = metadata.ValidationSummary.HasFailures;
            OpenWebsiteCommand = ReactiveCommand.Create(() => Utils.OpenWebsite(new Uri($"https://www.wabbajack.org/modlist/{Metadata.Links.MachineURL}")));
            ExecuteCommand     = ReactiveCommand.CreateFromObservable <Unit, Unit>(
                canExecute: this.WhenAny(x => x.IsBroken).Select(x => !x),
                execute: (unit) =>
                Observable.Return(unit)
                .WithLatestFrom(
                    this.WhenAny(x => x.Exists),
                    (_, e) => e)
                // Do any download work on background thread
                .ObserveOn(RxApp.TaskpoolScheduler)
                .SelectTask(async(exists) =>
            {
                if (!exists)
                {
                    try
                    {
                        var success = await Download();
                        if (!success)
                        {
                            Error = ErrorResponse.Fail("Download was marked unsuccessful");
                            return(false);
                        }
                    }
                    catch (Exception ex)
                    {
                        Error = ErrorResponse.Fail(ex);
                        return(false);
                    }
                    // Return an updated check on exists
                    return(Location.Exists);
                }
                return(exists);
            })
                .Where(exists => exists)
                // Do any install page swap over on GUI thread
                .ObserveOnGuiThread()
                .Select(_ =>
            {
                _parent.MWVM.OpenInstaller(Location);

                // Wait for modlist member to be filled, then open its readme
                return(_parent.MWVM.Installer.Value.WhenAny(x => x.ModList)
                       .NotNull()
                       .Take(1)
                       .Do(modList =>
                {
                    try
                    {
                        modList.OpenReadme();
                    }
                    catch (Exception ex)
                    {
                        Utils.Error(ex);
                    }
                }));
            })
                .Switch()
                .Unit());

            _Exists = Observable.Interval(TimeSpan.FromSeconds(0.5))
                      .Unit()
                      .StartWith(Unit.Default)
                      .FlowSwitch(_parent.WhenAny(x => x.IsActive))
                      .Select(_ =>
            {
                try
                {
                    return(!metadata.NeedsDownload(Location));
                }
                catch (Exception)
                {
                    return(true);
                }
            })
                      .ToGuiProperty(this, nameof(Exists));

            var imageObs = Observable.Return(Metadata.Links.ImageUri)
                           .DownloadBitmapImage((ex) => Utils.Log($"Error downloading modlist image {Metadata.Title}"));

            _Image = imageObs
                     .ToGuiProperty(this, nameof(Image));

            _LoadingImage = imageObs
                            .Select(x => false)
                            .StartWith(true)
                            .ToGuiProperty(this, nameof(LoadingImage));
        }
Esempio n. 54
0
        public NotificationsViewModel(IApplicationService applicationService)
        {
            _applicationService = applicationService;

            var whenNotificationsChange =
                _notifications.Changed.Select(_ => Unit.Default)
                .Merge(_notifications.ItemChanged.Select(_ => Unit.Default));

            _groupedNotifications = whenNotificationsChange.Select(_ =>
                                                                   _notifications.GroupBy(x => x.Repository.FullName)
                                                                   .Select(x => new NotificationGroupViewModel(x.Key, new ReactiveList <NotificationModel>(x), __ => { })))
                                    .ToProperty(this, t => t.GroupedNotifications);

            LoadCommand = ReactiveCommand.CreateAsyncTask(t =>
            {
                var req = applicationService.Client.Notifications.GetAll(all: Filter.All, participating: Filter.Participating);
                return(this.RequestModel(req, t as bool?, response => _notifications.Reset(response.Data)));
            });

            GoToNotificationCommand = ReactiveCommand.Create();
            GoToNotificationCommand.OfType <NotificationModel>().Subscribe(GoToNotification);


            var canReadAll = _notifications.CountChanged.Select(x => x > 0).CombineLatest(
                this.WhenAnyValue(x => x.ShownIndex).Select(x => x != 2), (x, y) => x & y);

            ReadAllCommand = ReactiveCommand.CreateAsyncTask(canReadAll, async t =>
            {
                try
                {
                    if (!_notifications.Any())
                    {
                        return;
                    }
                    await applicationService.Client.ExecuteAsync(applicationService.Client.Notifications.MarkAsRead());
                    _notifications.Clear();
                }
                catch (Exception e)
                {
                    throw new Exception("Unable to mark all notifications as read. Please try again.", e);
                }
            });

            ReadRepositoriesCommand = ReactiveCommand.CreateAsyncTask(async t =>
            {
                try
                {
                    var repo = t as string;
                    if (repo == null)
                    {
                        return;
                    }
                    var repoId = new RepositoryIdentifier(repo);
                    await applicationService.Client.ExecuteAsync(applicationService.Client.Notifications.MarkRepoAsRead(repoId.Owner, repoId.Name));
                    _notifications.RemoveAll(_notifications.Where(x => string.Equals(x.Repository.FullName, repo, StringComparison.OrdinalIgnoreCase)).ToList());
                }
                catch (Exception e)
                {
                    throw new Exception("Unable to mark repositories' notifications as read. Please try again.", e);
                }
            });

            this.WhenAnyValue(x => x.ShownIndex).Subscribe(x =>
            {
                switch (x)
                {
                case 0:
                    Filter = NotificationsFilterModel.CreateUnreadFilter();
                    break;

                case 1:
                    Filter = NotificationsFilterModel.CreateParticipatingFilter();
                    break;

                default:
                    Filter = NotificationsFilterModel.CreateAllFilter();
                    break;
                }
            });

            this.WhenAnyValue(x => x.Filter).Skip(1).Subscribe(x => LoadCommand.ExecuteIfCan());
        }
Esempio n. 55
0
        public SourceTreeViewModel(IApplicationService applicationService)
        {
            Branch = "master";
            Path   = string.Empty;

            var content = new ReactiveList <ContentModel>();

            Content = content.CreateDerivedCollection(
                x => CreateSourceItemViewModel(x),
                filter: x => x.Name.ContainsKeyword(SearchKeyword),
                signalReset: this.WhenAnyValue(x => x.SearchKeyword));

            _canAddFile = this.WhenAnyValue(x => x.TrueBranch, y => y.PushAccess)
                          .Select(x => x.Item1 && x.Item2.HasValue && x.Item2.Value)
                          .ToProperty(this, x => x.CanAddFile);

            this.WhenAnyValue(x => x.Path, y => y.RepositoryName, (x, y) => new { Path = x, Repo = y })
            .Subscribe(x =>
            {
                if (string.IsNullOrEmpty(x.Path))
                {
                    Title = string.IsNullOrEmpty(x.Repo) ? "Source" : x.Repo;
                }
                else
                {
                    var split = x.Path.TrimEnd('/').Split('/');
                    Title     = split[split.Length - 1];
                }
            });

            GoToAddFileCommand = ReactiveCommand.Create(
                this.WhenAnyValue(x => x.PushAccess, x => x.TrueBranch)
                .Select(x => x.Item1.HasValue && x.Item1.Value && x.Item2))
                                 .WithSubscription(_ =>
            {
                var vm             = this.CreateViewModel <CreateFileViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName  = RepositoryName;
                vm.Branch          = Branch;
                vm.Path            = Path;
                vm.SaveCommand.Subscribe(z => LoadCommand.ExecuteIfCan());
                NavigateTo(vm);
            });

            LoadCommand = ReactiveCommand.CreateAsyncTask(async _ =>
            {
                if (!PushAccess.HasValue)
                {
                    applicationService.GitHubClient.Repository.Get(RepositoryOwner, RepositoryName)
                    .ToBackground(x => PushAccess = x.Permissions.Push);
                }

                var path = Path;
                if (string.Equals(path, "/", StringComparison.OrdinalIgnoreCase))
                {
                    path = string.Empty;
                }

                var request  = applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].GetContent(Path, Branch);
                var data     = new List <ContentModel>();
                var response = await applicationService.Client.ExecuteAsync(request);
                data.AddRange(response.Data);
                while (response.More != null)
                {
                    response = await applicationService.Client.ExecuteAsync(response.More);
                    data.AddRange(response.Data);
                }
                content.Reset(data.OrderBy(y => y.Type).ThenBy(y => y.Name));
            });
        }
        public RepositoryCloneViewModel(
            IRepositoryHost repositoryHost,
            IRepositoryCloneService cloneService,
            IOperatingSystem operatingSystem,
            INotificationService notificationService,
            IUsageTracker usageTracker)
        {
            this.repositoryHost      = repositoryHost;
            this.cloneService        = cloneService;
            this.operatingSystem     = operatingSystem;
            this.notificationService = notificationService;
            this.usageTracker        = usageTracker;

            Title = string.Format(CultureInfo.CurrentCulture, Resources.CloneTitle, repositoryHost.Title);

            Repositories = new TrackingCollection <IRepositoryModel>();
            repositories.ProcessingDelay = TimeSpan.Zero;
            repositories.Comparer        = OrderedComparer <IRepositoryModel> .OrderBy(x => x.Owner).ThenBy(x => x.Name).Compare;

            repositories.Filter        = FilterRepository;
            repositories.NewerComparer = OrderedComparer <IRepositoryModel> .OrderByDescending(x => x.UpdatedAt).Compare;

            filterTextIsEnabled = this.WhenAny(x => x.IsLoading, x => x.Value)
                                  .Select(x => !x && repositories.UnfilteredCount > 0)
                                  .ToProperty(this, x => x.FilterTextIsEnabled);

            this.WhenAny(x => x.FilterTextIsEnabled, x => x.IsLoading, x => x.LoadingFailed
                         , (any, loading, failed) => !any.Value && !loading.Value && !failed.Value)
            .Subscribe(x => NoRepositoriesFound = x);

            this.WhenAny(x => x.FilterText, x => x.Value)
            .DistinctUntilChanged(StringComparer.OrdinalIgnoreCase)
            .Throttle(TimeSpan.FromMilliseconds(100), RxApp.MainThreadScheduler)
            .Subscribe(_ => repositories.Filter = FilterRepository);

            var baseRepositoryPath = this.WhenAny(
                x => x.BaseRepositoryPath,
                x => x.SelectedRepository,
                (x, y) => x.Value);

            BaseRepositoryPathValidator = ReactivePropertyValidator.ForObservable(baseRepositoryPath)
                                          .IfNullOrEmpty(Resources.RepositoryCreationClonePathEmpty)
                                          .IfTrue(x => x.Length > 200, Resources.RepositoryCreationClonePathTooLong)
                                          .IfContainsInvalidPathChars(Resources.RepositoryCreationClonePathInvalidCharacters)
                                          .IfPathNotRooted(Resources.RepositoryCreationClonePathInvalid)
                                          .IfTrue(IsAlreadyRepoAtPath, Resources.RepositoryNameValidatorAlreadyExists);

            var canCloneObservable = this.WhenAny(
                x => x.SelectedRepository,
                x => x.BaseRepositoryPathValidator.ValidationResult.IsValid,
                (x, y) => x.Value != null && y.Value);

            canClone     = canCloneObservable.ToProperty(this, x => x.CanClone);
            CloneCommand = ReactiveCommand.CreateAsyncObservable(canCloneObservable, OnCloneRepository);

            browseForDirectoryCommand.Subscribe(_ => ShowBrowseForDirectoryDialog());
            this.WhenAny(x => x.BaseRepositoryPathValidator.ValidationResult, x => x.Value)
            .Subscribe();
            BaseRepositoryPath  = cloneService.DefaultClonePath;
            NoRepositoriesFound = true;
        }
Esempio n. 57
0
 private CommandVM(ReactiveCommand <Unit, Unit> cmd)
 {
     Command     = cmd;
     _CanExecute = cmd.CanExecute
                   .ToProperty(this, nameof(CanExecute), initialValue: false);
 }
Esempio n. 58
0
        public PatchersRunVM(ConfigurationVM parent, ProfileVM profile)
        {
            Config         = parent;
            RunningProfile = profile;
            Patchers.AddOrUpdate(RunningProfile.Patchers.Items
                                 .Where(x => x.IsOn)
                                 .Select(p => p.ToRunner(this)));
            PatchersDisplay = Patchers.Connect()
                              .ToObservableCollection(this);
            if (parent.SelectedPatcher != null &&
                Patchers.TryGetValue(parent.SelectedPatcher.InternalID, out var run))
            {
                SelectedPatcher = run;
            }

            BackCommand = ReactiveCommand.Create(() =>
            {
                parent.SelectedPatcher    = SelectedPatcher?.Config;
                parent.MainVM.ActivePanel = parent;
            },
                                                 canExecute: this.WhenAnyValue(x => x.Running)
                                                 .Select(running => !running));
            CancelCommand = ReactiveCommand.CreateFromTask(
                execute: Cancel,
                canExecute: this.WhenAnyValue(x => x.Running));

            _reporter.Overall
            .ObserveOnGui()
            .Subscribe(ex =>
            {
                Log.Logger.Error(ex, "Error while running patcher pipeline");
                ResultError = ex;
            })
            .DisposeWith(this);
            _reporter.PrepProblem
            .Select(data => (data, type: "prepping"))
            .Merge(_reporter.RunProblem
                   .Select(data => (data, type: "running")))
            .ObserveOnGui()
            .Subscribe(i =>
            {
                var vm          = Patchers.Get(i.data.Key);
                vm.State        = GetResponse <RunState> .Fail(RunState.Error, i.data.Error);
                SelectedPatcher = vm;
                Log.Logger
                .ForContext(nameof(PatcherVM.DisplayName), i.data.Run.Name)
                .Error(i.data.Error, $"Error while prepping {i.type}");
            })
            .DisposeWith(this);
            _reporter.Starting
            .ObserveOnGui()
            .Subscribe(i =>
            {
                var vm   = Patchers.Get(i.Key);
                vm.State = GetResponse <RunState> .Succeed(RunState.Started);
                Log.Logger
                .ForContext(nameof(PatcherVM.DisplayName), i.Run.Name)
                .Information($"Starting");
            })
            .DisposeWith(this);
            _reporter.RunSuccessful
            .ObserveOnGui()
            .Subscribe(i =>
            {
                var vm   = Patchers.Get(i.Key);
                vm.State = GetResponse <RunState> .Succeed(RunState.Finished);
                Log.Logger
                .ForContext(nameof(PatcherVM.DisplayName), i.Run.Name)
                .Information("Finished {RunTime}", vm.RunTime);
            })
            .DisposeWith(this);
            _reporter.Output
            .Subscribe(s =>
            {
                Log.Logger
                .ForContextIfNotNull(nameof(PatcherVM.DisplayName), s.Run?.Name)
                .Information(s.String);
            })
            .DisposeWith(this);
            _reporter.Error
            .Subscribe(s =>
            {
                Log.Logger
                .ForContextIfNotNull(nameof(PatcherVM.DisplayName), s.Run?.Name)
                .Error(s.String);
            })
            .DisposeWith(this);

            // Clear selected patcher on showing error
            this.ShowOverallErrorCommand.StartingExecution()
            .Subscribe(_ => this.SelectedPatcher = null)
            .DisposeWith(this);

            _DetailDisplay = Observable.Merge(
                this.WhenAnyValue(x => x.SelectedPatcher)
                .Select(i => i as object),
                this.ShowOverallErrorCommand.EndingExecution()
                .Select(_ => ResultError == null ? null : new OverallErrorVM(ResultError)))
                             .ToGuiProperty(this, nameof(DetailDisplay));
        }
        public CoinViewModel(Wallet wallet, CoinListViewModel owner, SmartCoin model)
        {
            Global = Locator.Current.GetService <Global>();

            Model  = model;
            Wallet = wallet;
            Owner  = owner;

            RefreshSmartCoinStatus();

            Disposables = new CompositeDisposable();

            _coinJoinInProgress = Model
                                  .WhenAnyValue(x => x.CoinJoinInProgress)
                                  .ToProperty(this, x => x.CoinJoinInProgress, scheduler: RxApp.MainThreadScheduler)
                                  .DisposeWith(Disposables);

            _unspent = Model
                       .WhenAnyValue(x => x.Unspent)
                       .ToProperty(this, x => x.Unspent, scheduler: RxApp.MainThreadScheduler)
                       .DisposeWith(Disposables);

            _confirmed = Model
                         .WhenAnyValue(x => x.Confirmed)
                         .ToProperty(this, x => x.Confirmed, scheduler: RxApp.MainThreadScheduler)
                         .DisposeWith(Disposables);

            _cluster = Model
                       .WhenAnyValue(x => x.Clusters, x => x.Clusters.Labels)
                       .Select(x => x.Item2.ToString())
                       .ToProperty(this, x => x.Clusters, scheduler: RxApp.MainThreadScheduler)
                       .DisposeWith(Disposables);

            _unavailable = Model
                           .WhenAnyValue(x => x.Unavailable)
                           .ToProperty(this, x => x.Unavailable, scheduler: RxApp.MainThreadScheduler)
                           .DisposeWith(Disposables);

            this.WhenAnyValue(x => x.Status)
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(_ => this.RaisePropertyChanged(nameof(ToolTip)));

            Observable
            .Merge(Model.WhenAnyValue(x => x.IsBanned, x => x.SpentAccordingToBackend, x => x.Confirmed, x => x.CoinJoinInProgress).Select(_ => Unit.Default))
            .Merge(Observable.FromEventPattern(Wallet.ChaumianClient, nameof(Wallet.ChaumianClient.StateUpdated)).Select(_ => Unit.Default))
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(_ => RefreshSmartCoinStatus())
            .DisposeWith(Disposables);

            Global.BitcoinStore.SmartHeaderChain
            .WhenAnyValue(x => x.TipHeight).Select(_ => Unit.Default)
            .Merge(Model.WhenAnyValue(x => x.Height).Select(_ => Unit.Default))
            .Throttle(TimeSpan.FromSeconds(0.1))                     // DO NOT TAKE THIS THROTTLE OUT, OTHERWISE SYNCING WITH COINS IN THE WALLET WILL STACKOVERFLOW!
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(_ => this.RaisePropertyChanged(nameof(Confirmations)))
            .DisposeWith(Disposables);

            Global.UiConfig
            .WhenAnyValue(x => x.LurkingWifeMode)
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(_ =>
            {
                this.RaisePropertyChanged(nameof(AmountBtc));
                this.RaisePropertyChanged(nameof(Clusters));
            }).DisposeWith(Disposables);

            DequeueCoin = ReactiveCommand.Create(() => Owner.PressDequeue(Model), this.WhenAnyValue(x => x.CoinJoinInProgress));

            OpenCoinInfo = ReactiveCommand.Create(() =>
            {
                var shell = IoC.Get <IShell>();

                var coinInfo = shell.Documents?.OfType <CoinInfoTabViewModel>()?.FirstOrDefault(x => x.Coin?.Model == Model);

                if (coinInfo is null)
                {
                    coinInfo = new CoinInfoTabViewModel(this);
                    shell.AddDocument(coinInfo);
                }

                shell.Select(coinInfo);
            });

            CopyClusters = ReactiveCommand.CreateFromTask(async() => await Application.Current.Clipboard.SetTextAsync(Clusters));

            Observable
            .Merge(DequeueCoin.ThrownExceptions)                     // Don't notify about it. Dequeue failure (and success) is notified by other mechanism.
            .Merge(OpenCoinInfo.ThrownExceptions)
            .Merge(CopyClusters.ThrownExceptions)
            .ObserveOn(RxApp.TaskpoolScheduler)
            .Subscribe(ex => Logger.LogError(ex));
        }
Esempio n. 60
0
        public RenameFileViewModel(
            IProviderViewModel providerViewModel,
            IProvider provider,
            IScheduler current,
            IScheduler main)
        {
            _oldName = providerViewModel
                       .WhenAnyValue(x => x.SelectedFile)
                       .Select(file => file?.Name)
                       .ToProperty(this, x => x.OldName, scheduler: current);

            var canInteract = providerViewModel
                              .WhenAnyValue(x => x.CanInteract);

            var oldNameValid = this
                               .WhenAnyValue(x => x.OldName)
                               .Select(old => !string.IsNullOrWhiteSpace(old));

            var canOpen = this
                          .WhenAnyValue(x => x.IsVisible)
                          .Select(visible => !visible)
                          .CombineLatest(oldNameValid, (visible, old) => visible && old)
                          .CombineLatest(canInteract, (open, interact) => open && interact);

            _open = ReactiveCommand.Create(
                () => { IsVisible = true; },
                canOpen, main);

            var canClose = this
                           .WhenAnyValue(x => x.IsVisible)
                           .Select(visible => visible);

            _close = ReactiveCommand.Create(
                () => { IsVisible = false; },
                canClose, main);

            var canRename = this
                            .WhenAnyValue(x => x.NewName)
                            .Select(name => !string.IsNullOrWhiteSpace(name))
                            .CombineLatest(oldNameValid, (old, name) => old && name);

            _rename = ReactiveCommand.CreateFromTask(
                () => provider.RenameFile(providerViewModel.SelectedFile.Path, NewName),
                canRename, main);

            _isLoading = _rename
                         .IsExecuting
                         .ToProperty(this, x => x.IsLoading, scheduler: current);

            _hasErrors = _rename
                         .ThrownExceptions
                         .Select(exception => true)
                         .Merge(_close.Select(x => false))
                         .ToProperty(this, x => x.HasErrors, scheduler: current);

            _errorMessage = _rename
                            .ThrownExceptions
                            .Select(exception => exception.Message)
                            .Log(this, $"Rename file error occured in {provider.Name} for {OldName}")
                            .Merge(_close.Select(x => string.Empty))
                            .ToProperty(this, x => x.ErrorMessage, scheduler: current);

            _rename.InvokeCommand(_close);
            _close.Subscribe(x => NewName = string.Empty);
        }