public override async Task Initialize() { await base.Initialize(); await TimeEntriesViewModel.Initialize(); await SuggestionsViewModel.Initialize(); await RatingViewModel.Initialize(); SyncProgressState = dataSource .SyncManager .ProgressObservable .AsDriver(schedulerProvider); var isWelcome = onboardingStorage.IsNewUser; var noTimeEntries = TimeEntriesViewModel.Empty .Select(e => e && SuggestionsViewModel.IsEmpty) .DistinctUntilChanged(); ShouldShowEmptyState = ObservableAddons.CombineLatestAll( isWelcome, noTimeEntries ) .DistinctUntilChanged() .AsDriver(schedulerProvider); ShouldShowWelcomeBack = ObservableAddons.CombineLatestAll( isWelcome.Select(b => !b), noTimeEntries ) .StartWith(false) .DistinctUntilChanged() .AsDriver(schedulerProvider); ShouldShowRunningTimeEntryNotification = userPreferences.AreRunningTimerNotificationsEnabledObservable; ShouldShowStoppedTimeEntryNotification = userPreferences.AreStoppedTimerNotificationsEnabledObservable; CurrentRunningTimeEntry = dataSource .TimeEntries .CurrentlyRunningTimeEntry .AsDriver(schedulerProvider); CurrentTimeEntryHasDescription = CurrentRunningTimeEntry .Select(te => !string.IsNullOrWhiteSpace(te?.Description)) .DistinctUntilChanged(); IsTimeEntryRunning = CurrentRunningTimeEntry .Select(te => te != null) .DistinctUntilChanged(); timeService .CurrentDateTimeObservable .Where(_ => currentTimeEntryStart != null) .Subscribe(currentTime => CurrentTimeEntryElapsedTime = currentTime - currentTimeEntryStart.Value) .DisposedBy(disposeBag); interactorFactory .GetItemsThatFailedToSync() .Execute() .Select(i => i.Count()) .Subscribe(n => NumberOfSyncFailures = n) .DisposedBy(disposeBag); ShouldReloadTimeEntryLog = Observable.Merge( timeService.MidnightObservable.SelectUnit(), timeService.SignificantTimeChangeObservable.SelectUnit() ); switch (urlNavigationAction) { case ApplicationUrls.Main.Action.Continue: await continueMostRecentEntry(); break; case ApplicationUrls.Main.Action.Stop: await stopTimeEntry(); break; } ratingViewExperiment .RatingViewShouldBeVisible .Subscribe(presentRatingViewIfNeeded) .DisposedBy(disposeBag); onboardingStorage.StopButtonWasTappedBefore .Subscribe(hasBeen => hasStopButtonEverBeenUsed = hasBeen) .DisposedBy(disposeBag); dataSource .TimeEntries .CurrentlyRunningTimeEntry .Subscribe(setRunningEntry) .DisposedBy(disposeBag); }
public override async Task Initialize() { await base.Initialize(); await TimeEntriesViewModel.Initialize(); await SuggestionsViewModel.Initialize(); await RatingViewModel.Initialize(); SyncProgressState = dataSource .SyncManager .ProgressObservable .AsDriver(SchedulerProvider); var isWelcome = onboardingStorage.IsNewUser; var noTimeEntries = Observable .CombineLatest(TimeEntriesViewModel.Empty, SuggestionsViewModel.IsEmpty, (isTimeEntryEmpty, isSuggestionEmpty) => isTimeEntryEmpty && isSuggestionEmpty) .DistinctUntilChanged(); ShouldShowEmptyState = ObservableAddons.CombineLatestAll( isWelcome, noTimeEntries ) .DistinctUntilChanged() .AsDriver(SchedulerProvider); ShouldShowWelcomeBack = ObservableAddons.CombineLatestAll( isWelcome.Select(b => !b), noTimeEntries ) .StartWith(false) .DistinctUntilChanged() .AsDriver(SchedulerProvider); IsInManualMode = userPreferences .IsManualModeEnabledObservable .AsDriver(SchedulerProvider); ShouldShowRunningTimeEntryNotification = userPreferences.AreRunningTimerNotificationsEnabledObservable; ShouldShowStoppedTimeEntryNotification = userPreferences.AreStoppedTimerNotificationsEnabledObservable; CurrentRunningTimeEntry = dataSource .TimeEntries .CurrentlyRunningTimeEntry .AsDriver(SchedulerProvider); IsTimeEntryRunning = CurrentRunningTimeEntry .Select(te => te != null) .DistinctUntilChanged() .AsDriver(SchedulerProvider); var durationObservable = dataSource .Preferences .Current .Select(preferences => preferences.DurationFormat); ElapsedTime = TimeService .CurrentDateTimeObservable .CombineLatest(CurrentRunningTimeEntry, (now, te) => (now - te?.Start) ?? TimeSpan.Zero) .CombineLatest(durationObservable, (duration, format) => duration.ToFormattedString(format)) .AsDriver(SchedulerProvider); NumberOfSyncFailures = interactorFactory .GetItemsThatFailedToSync() .Execute() .Select(i => i.Count()) .AsDriver(SchedulerProvider); ShouldReloadTimeEntryLog = Observable.Merge( TimeService.MidnightObservable.SelectUnit(), TimeService.SignificantTimeChangeObservable.SelectUnit()) .AsDriver(SchedulerProvider); Refresh = rxActionFactory.FromAsync(refresh); OpenReports = rxActionFactory.FromAsync(openReports); OpenSettings = rxActionFactory.FromAsync(openSettings); OpenSyncFailures = rxActionFactory.FromAsync(openSyncFailures); SelectTimeEntry = rxActionFactory.FromAsync <long>(timeEntrySelected); DeleteTimeEntry = rxActionFactory.FromObservable <TimeEntryViewModel>(deleteTimeEntry); ContinueTimeEntry = rxActionFactory.FromObservable <TimeEntryViewModel>(continueTimeEntry); StartTimeEntry = rxActionFactory.FromAsync <bool>(startTimeEntry, IsTimeEntryRunning.Invert()); StopTimeEntry = rxActionFactory.FromAsync <TimeEntryStopOrigin>(stopTimeEntry, IsTimeEntryRunning); switch (urlNavigationAction) { case ApplicationUrls.Main.Action.Continue: await continueMostRecentEntry(); break; case ApplicationUrls.Main.Action.Stop: await stopTimeEntry(TimeEntryStopOrigin.Deeplink); break; } ratingViewExperiment .RatingViewShouldBeVisible .Subscribe(presentRatingViewIfNeeded) .DisposedBy(disposeBag); onboardingStorage.StopButtonWasTappedBefore .Subscribe(hasBeen => hasStopButtonEverBeenUsed = hasBeen) .DisposedBy(disposeBag); interactorFactory.GetDefaultWorkspace() .TrackException <InvalidOperationException, IThreadSafeWorkspace>("MainViewModel.Initialize") .Execute() .Subscribe(intentDonationService.SetDefaultShortcutSuggestions) .DisposedBy(disposeBag); dataSource .Workspaces .Created .Subscribe(_ => onWorkspaceCreated()) .DisposedBy(disposeBag); dataSource .Workspaces .Updated .Subscribe(onWorkspaceUpdated) .DisposedBy(disposeBag); }