Пример #1
0
        public override async Task Initialize()
        {
            await base.Initialize();

            SyncFailures = await interactorFactory
                           .GetItemsThatFailedToSync().Execute()
                           .FirstAsync();
        }
Пример #2
0
        public override async Task Initialize()
        {
            await base.Initialize();

            await TimeEntriesViewModel.Initialize();

            await TimeEntriesLogViewModel.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);

            var connectableTimeEntryIsRunning =
                dataSource
                .TimeEntries
                .CurrentlyRunningTimeEntry
                .Do(setRunningEntry)
                .Select(timeEntry => timeEntry != null)
                .DistinctUntilChanged()
                .Replay(1);

            connectableTimeEntryIsRunning.Connect();

            IsTimeEntryRunning = connectableTimeEntryIsRunning.AsDriver(schedulerProvider);

            CurrentTimeEntryHasDescription = dataSource
                                             .TimeEntries
                                             .CurrentlyRunningTimeEntry
                                             .Select(te => !string.IsNullOrWhiteSpace(te?.Description))
                                             .DistinctUntilChanged()
                                             .AsDriver(schedulerProvider);

            timeService
            .CurrentDateTimeObservable
            .Where(_ => currentTimeEntryStart != null)
            .Subscribe(currentTime => CurrentTimeEntryElapsedTime = currentTime - currentTimeEntryStart.Value)
            .DisposedBy(disposeBag);

            dataSource
            .SyncManager
            .ProgressObservable
            .Subscribe(progress => SyncingProgress = progress)
            .DisposedBy(disposeBag);

            interactorFactory
            .GetItemsThatFailedToSync()
            .Execute()
            .Select(i => i.Count())
            .Subscribe(n => NumberOfSyncFailures = n)
            .DisposedBy(disposeBag);

            timeService.MidnightObservable
            .Subscribe(onMidnight)
            .DisposedBy(disposeBag);

            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);
        }
Пример #3
0
        public override async Task Initialize()
        {
            await base.Initialize();

            await TimeEntriesLogViewModel.Initialize();

            await SuggestionsViewModel.Initialize();

            TimeEntryCardVisibility = dataSource
                                      .TimeEntries
                                      .CurrentlyRunningTimeEntry
                                      .Throttle(currentTimeEntryDueTime, scheduler) // avoid overwhelming the UI with frequent updates
                                      .Do(setRunningEntry)
                                      .Select(timeEntry => timeEntry != null);

            var tickDisposable = timeService
                                 .CurrentDateTimeObservable
                                 .Where(_ => currentTimeEntryStart != null)
                                 .Subscribe(currentTime => CurrentTimeEntryElapsedTime = currentTime - currentTimeEntryStart.Value);

            var syncManagerDisposable = dataSource
                                        .SyncManager
                                        .ProgressObservable
                                        .Subscribe(progress => SyncingProgress = progress);

            var isEmptyChangedDisposable = Observable.Empty <Unit>()
                                           .Merge(dataSource.TimeEntries.Updated.Select(_ => Unit.Default))
                                           .Merge(dataSource.TimeEntries.Deleted.Select(_ => Unit.Default))
                                           .Merge(dataSource.TimeEntries.Created.Select(_ => Unit.Default))
                                           .Subscribe(_ =>
            {
                RaisePropertyChanged(nameof(ShouldShowTimeEntriesLog));
                RaisePropertyChanged(nameof(ShouldShowWelcomeBack));
                RaisePropertyChanged(nameof(ShouldShowEmptyState));
                RaisePropertyChanged(nameof(IsLogEmpty));
                RaisePropertyChanged(nameof(TimeEntriesCount));
            });

            var getNumberOfSyncFailuresDisposable = interactorFactory
                                                    .GetItemsThatFailedToSync()
                                                    .Execute()
                                                    .Select(i => i.Count())
                                                    .Subscribe(n => NumberOfSyncFailures = n);

            disposeBag.Add(tickDisposable);
            disposeBag.Add(syncManagerDisposable);
            disposeBag.Add(isEmptyChangedDisposable);
            disposeBag.Add(getNumberOfSyncFailuresDisposable);

            switch (urlNavigationAction)
            {
            case ApplicationUrls.Main.Action.Continue:
                await continueMostRecentEntry();

                break;

            case ApplicationUrls.Main.Action.Stop:
                await stopTimeEntry();

                break;
            }
        }
Пример #4
0
        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);
        }
Пример #5
0
        public override async Task Initialize()
        {
            await base.Initialize();

            interactorFactory.GetCurrentUser().Execute()
            .Select(u => u.Id)
            .Subscribe(analyticsService.SetAppCenterUserId);

            await SuggestionsViewModel.Initialize();

            await RatingViewModel.Initialize();

            widgetsService.Start();

            SyncProgressState = 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 = dataSource.TimeEntries
                                 .CurrentlyRunningTimeEntry
                                 .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);
            OpenSettings      = rxActionFactory.FromAsync(openSettings);
            OpenSyncFailures  = rxActionFactory.FromAsync(openSyncFailures);
            SelectTimeEntry   = rxActionFactory.FromAsync <EditTimeEntryInfo>(timeEntrySelected);
            ContinueTimeEntry = rxActionFactory.FromObservable <ContinueTimeEntryInfo, IThreadSafeTimeEntry>(continueTimeEntry);
            StartTimeEntry    = rxActionFactory.FromAsync <bool>(startTimeEntry, IsTimeEntryRunning.Invert());
            StopTimeEntry     = rxActionFactory.FromObservable <TimeEntryStopOrigin>(stopTimeEntry, IsTimeEntryRunning);

            ShouldShowRatingView = Observable.Merge(
                ratingViewExperiment.RatingViewShouldBeVisible,
                RatingViewModel.HideRatingView.SelectValue(false),
                hideRatingView.AsObservable().SelectValue(false)
                )
                                   .Select(canPresentRating)
                                   .DistinctUntilChanged()
                                   .Do(trackRatingViewPresentation)
                                   .AsDriver(schedulerProvider);

            OnboardingStorage.StopButtonWasTappedBefore
            .Subscribe(hasBeen => hasStopButtonEverBeenUsed = hasBeen)
            .DisposedBy(disposeBag);

            if (platformInfo.Platform == Platform.Giskard)
            {
                analyticsService.ApplicationInstallLocation.Track(platformInfo.InstallLocation);
            }

            SyncProgressState
            .Subscribe(postAccessibilityAnnouncementAboutSync)
            .DisposedBy(disposeBag);
        }
Пример #6
0
        public override async Task Initialize()
        {
            await base.Initialize();

            await TimeEntriesLogViewModel.Initialize();

            await SuggestionsViewModel.Initialize();

            await RatingViewModel.Initialize();

            var connectableTimeEntryIsRunning =
                dataSource
                .TimeEntries
                .CurrentlyRunningTimeEntry
                .Do(setRunningEntry)
                .Select(timeEntry => timeEntry != null)
                .DistinctUntilChanged()
                .Replay(1);

            connectableTimeEntryIsRunning.Connect();

            IsTimeEntryRunning = connectableTimeEntryIsRunning;

            var tickDisposable = timeService
                                 .CurrentDateTimeObservable
                                 .Where(_ => currentTimeEntryStart != null)
                                 .Subscribe(currentTime => CurrentTimeEntryElapsedTime = currentTime - currentTimeEntryStart.Value);

            var syncManagerDisposable = dataSource
                                        .SyncManager
                                        .ProgressObservable
                                        .Subscribe(progress => SyncingProgress = progress);

            var isEmptyChangedDisposable = Observable.Empty <Unit>()
                                           .Merge(dataSource.TimeEntries.Updated.Select(_ => Unit.Default))
                                           .Merge(dataSource.TimeEntries.Deleted.Select(_ => Unit.Default))
                                           .Merge(dataSource.TimeEntries.Created.Select(_ => Unit.Default))
                                           .Subscribe((Unit _) =>
            {
                RaisePropertyChanged(nameof(ShouldShowTimeEntriesLog));
                RaisePropertyChanged(nameof(ShouldShowWelcomeBack));
                RaisePropertyChanged(nameof(ShouldShowEmptyState));
                RaisePropertyChanged(nameof(IsLogEmpty));
                RaisePropertyChanged(nameof(TimeEntriesCount));
            });

            var getNumberOfSyncFailuresDisposable = interactorFactory
                                                    .GetItemsThatFailedToSync()
                                                    .Execute()
                                                    .Select(i => i.Count())
                                                    .Subscribe(n => NumberOfSyncFailures = n);

            disposeBag.Add(tickDisposable);
            disposeBag.Add(syncManagerDisposable);
            disposeBag.Add(isEmptyChangedDisposable);
            disposeBag.Add(getNumberOfSyncFailuresDisposable);

            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);
        }