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

            var defaultWorkspace = await interactorFactory.GetDefaultWorkspace().Execute();

            SelectedWorkspace.Accept(defaultWorkspace);
        }
Пример #2
0
        public override async Task Initialize()
        {
            await base.Initialize();

            await CalendarViewModel.Initialize();

            WorkspacesObservable
            .Subscribe(data => Workspaces = data)
            .DisposedBy(disposeBag);

            var user = await dataSource.User.Get();

            userId = user.Id;

            IInteractor <IObservable <IThreadSafeWorkspace> > workspaceInteractor;

            workspaceInteractor = interactorFactory.GetDefaultWorkspace();

            var workspace = await workspaceInteractor
                            .TrackException <InvalidOperationException, IThreadSafeWorkspace>("ReportsViewModel.Initialize")
                            .Execute();

            workspaceId = workspace.Id;
            workspaceSubject.OnNext(workspace);

            CalendarViewModel.SelectedDateRangeObservable
            .Subscribe(changeDateRange)
            .DisposedBy(disposeBag);

            reportSubject
            .AsObservable()
            .Do(setLoadingState)
            .SelectMany(_ =>
                        startDate == default(DateTimeOffset) || endDate == default(DateTimeOffset)
                       ? Observable.Empty <ProjectSummaryReport>()
                       : interactorFactory.GetProjectSummary(workspaceId, startDate, endDate).Execute())
            .Catch(Observable.Return <ProjectSummaryReport>(null))
            .Subscribe(onReport)
            .DisposedBy(disposeBag);

            dataSource.Preferences.Current
            .Subscribe(onPreferencesChanged)
            .DisposedBy(disposeBag);

            dataSource.User.Current
            .Select(currentUser => currentUser.BeginningOfWeek)
            .Subscribe(onBeginningOfWeekChanged)
            .DisposedBy(disposeBag);

            interactorFactory.ObserveDefaultWorkspaceId()
            .Execute()
            .Where(newWorkspaceId => newWorkspaceId != workspaceId)
            .SelectMany(id => interactorFactory.GetWorkspaceById(id).Execute())
            .Where(ws => !ws.IsInaccessible)
            .Subscribe(updateWorkspace)
            .DisposedBy(disposeBag);
        }
Пример #3
0
        public override async Task Initialize()
        {
            var user = await dataSource.User.Current.FirstAsync();

            var defaultWorkspace = await interactorFactory.GetDefaultWorkspace().Execute();

            Email               = user.Email;
            Name                = user.Fullname;
            Version             = userAgent.Version;
            workspaceId         = defaultWorkspace.Id;
            WorkspaceName       = defaultWorkspace.Name;
            IsManualModeEnabled = userPreferences.IsManualModeEnabled;
            BeginningOfWeek     = user.BeginningOfWeek;
            ImageUrl            = user.ImageUrl;

            var workspaces = await interactorFactory.GetAllWorkspaces().Execute();

            foreach (var workspace in workspaces)
            {
                Workspaces.Add(new SelectableWorkspaceViewModel(workspace, workspace.Id == workspaceId));
            }

            dataSource.Preferences.Current
            .Subscribe(updateFromPreferences);
        }
Пример #4
0
        public void Init(string action, string description)
        {
            urlNavigationAction = action;

            if (!string.IsNullOrEmpty(description))
            {
                interactorFactory.GetDefaultWorkspace()
                .TrackException <InvalidOperationException, IThreadSafeWorkspace>("MainViewModel.Init")
                .Execute()
                .SelectMany(workspace => interactorFactory
                            .CreateTimeEntry(description.AsTimeEntryPrototype(TimeService.CurrentDateTime, workspace.Id))
                            .Execute())
                .Subscribe()
                .DisposedBy(disposeBag);
            }
        }
Пример #5
0
        public IObservable <Suggestion> GetSuggestions()
        {
            var now          = timeService.CurrentDateTime;
            var startOfRange = now - lookBackTimeSpan;
            var endOfRange   = now + lookAheadTimeSpan;

            var eventsObservable = calendarService
                                   .GetEventsInRange(startOfRange, endOfRange)
                                   .Select(events => events.Where(eventHasDescription))
                                   .SelectMany(orderByOffset);

            var selectedUserCalendars = interactorFactory
                                        .GetUserCalendars()
                                        .Execute()
                                        .Select(calendars => calendars.Where(c => c.IsSelected));

            var eventsFromSelectedUserCalendars = eventsObservable.WithLatestFrom(selectedUserCalendars,
                                                                                  (calendarItem, calendars) =>
                                                                                  (calendarItem: calendarItem, userCalendarIds: calendars.Select(c => c.Id)))
                                                  .Where(tuple => tuple.userCalendarIds.Contains(tuple.calendarItem.CalendarId))
                                                  .Select(tuple => tuple.calendarItem);

            return(interactorFactory.GetDefaultWorkspace().Execute()
                   .CombineLatest(
                       eventsFromSelectedUserCalendars,
                       (workspace, calendarItem) => suggestionFromEvent(calendarItem, workspace.Id))
                   .Take(maxCalendarSuggestionCount)
                   .OnErrorResumeEmpty());
        }
        public override async Task Initialize()
        {
            await base.Initialize();

            startTimeEntryStopwatch = stopwatchProvider.Get(MeasuredOperation.OpenStartView);
            stopwatchProvider.Remove(MeasuredOperation.OpenStartView);

            defaultWorkspace = await interactorFactory.GetDefaultWorkspace()
                               .TrackException <InvalidOperationException, IThreadSafeWorkspace>("StartTimeEntryViewModel.Initialize")
                               .Execute();

            canCreateProjectsInWorkspace =
                await interactorFactory.GetAllWorkspaces().Execute().Select(allWorkspaces =>
                                                                            allWorkspaces.Any(ws => ws.IsEligibleForProjectCreation()));

            if (initialParameters != null)
            {
                var spans = new List <ISpan>();
                spans.Add(new TextSpan(initialParameters.EntryDescription));
                if (initialParameters.ProjectId != null)
                {
                    try
                    {
                        var project = await interactorFactory.GetProjectById((long)initialParameters.ProjectId).Execute();

                        spans.Add(new ProjectSpan(project));
                    }
                    catch
                    {
                        // Intentionally left blank
                    }
                }
                if (initialParameters.TagIds != null)
                {
                    try
                    {
                        var tags = initialParameters.TagIds.ToObservable()
                                   .SelectMany <long, IThreadSafeTag>(tagId => interactorFactory.GetTagById(tagId).Execute())
                                   .ToEnumerable();
                        spans.AddRange(tags.Select(tag => new TagSpan(tag)));
                    }
                    catch
                    {
                        // Intentionally left blank
                    }
                }

                textFieldInfo.Accept(textFieldInfo.Value.ReplaceSpans(spans.ToImmutableList()));
            }
            else
            {
                textFieldInfo.Accept(Autocomplete.TextFieldInfo.Empty(parameter?.WorkspaceId ?? defaultWorkspace.Id));
            }

            hasAnyTags     = (await DataSource.Tags.GetAll()).Any();
            hasAnyProjects = (await DataSource.Projects.GetAll()).Any();
        }
Пример #7
0
        public async Task PickDefaultWorkspace()
        {
            var defaultWorkspace = await interactorFactory.GetDefaultWorkspace().Execute();

            var parameters          = WorkspaceParameters.Create(defaultWorkspace.Id, Resources.SetDefaultWorkspace, allowQuerying: false);
            var selectedWorkspaceId =
                await navigationService
                .Navigate <SelectWorkspaceViewModel, WorkspaceParameters, long>(parameters);

            await changeDefaultWorkspace(selectedWorkspaceId);
        }
Пример #8
0
        public override async Task Initialize()
        {
            var workspace = await interactorFactory.GetDefaultWorkspace().Execute();

            areCustomColorsEnabled = await interactorFactory.AreCustomColorsEnabledForWorkspace(workspace.Id).Execute();

            workspaceId   = initialWorkspaceId = workspace.Id;
            WorkspaceName = workspace.Name;

            await setupNameAlreadyTakenError();
        }
Пример #9
0
        private async Task pickDefaultWorkspace()
        {
            var defaultWorkspace = await interactorFactory.GetDefaultWorkspace()
                                   .TrackException <InvalidOperationException, IThreadSafeWorkspace>("SettingsViewModel.PickDefaultWorkspace")
                                   .Execute();

            var selectedWorkspaceId =
                await navigationService
                .Navigate <SelectWorkspaceViewModel, long, long>(defaultWorkspace.Id);

            await changeDefaultWorkspace(selectedWorkspaceId);
        }
Пример #10
0
        public static async Task Update(this DeeplinkUpdateTimeEntryParameters parameters, IInteractorFactory interactorFactory, ITimeService timeService)
        {
            var timeEntryId = parameters.TimeEntryId;
            var workspaceId = parameters.WorkspaceId;
            var startTime   = parameters.StartTime ?? timeService.CurrentDateTime;
            var stopTime    = parameters.StopTime;
            var description = parameters.Description;
            var projectId   = parameters.ProjectId;
            var taskId      = parameters.TaskId;
            var tagIds      = parameters.TagIds;
            var isBillable  = parameters.IsBillable ?? false;

            var timeEntryToUpdate = await interactorFactory.GetTimeEntryById(timeEntryId).Execute();

            if (!workspaceId.HasValue)
            {
                var defaultWorkspace = await interactorFactory.GetDefaultWorkspace().Execute();

                workspaceId = defaultWorkspace.Id;
            }

            var newWorkspaceId = parameters.HasWorkspaceId ? workspaceId.Value : timeEntryToUpdate.WorkspaceId;
            var newStartTime   = parameters.HasStartTime ? startTime : timeEntryToUpdate.Start;
            var newStopTime    = parameters.HasStopTime ? stopTime : timeEntryToUpdate.StopTime();
            var newDescription = parameters.HasDescription ? description : timeEntryToUpdate.Description;
            var newProjectId   = parameters.HasProjectId ? projectId : timeEntryToUpdate.ProjectId;
            var newTaskId      = parameters.HasTaskId ? taskId : timeEntryToUpdate.TaskId;
            var newTagIds      = parameters.HasTagIds ? tagIds : timeEntryToUpdate.TagIds;
            var newIsBillable  = parameters.HasIsBillable ? isBillable : timeEntryToUpdate.Billable;

            var editTimeEntryDto = new EditTimeEntryDto
            {
                Id          = timeEntryId,
                WorkspaceId = newWorkspaceId,
                StartTime   = newStartTime,
                StopTime    = newStopTime,
                Description = newDescription,
                ProjectId   = newProjectId,
                TaskId      = newTaskId,
                TagIds      = newTagIds,
                Billable    = newIsBillable,
            };

            await interactorFactory.UpdateTimeEntry(editTimeEntryDto).Execute();
        }
Пример #11
0
        private async Task pickDefaultWorkspace()
        {
            var defaultWorkspace = await interactorFactory.GetDefaultWorkspace()
                                   .TrackException <InvalidOperationException, IThreadSafeWorkspace>("SettingsViewModel.PickDefaultWorkspace")
                                   .Execute();

            var selectedWorkspaceId =
                await Navigate <SelectWorkspaceViewModel, SelectWorkspaceParameters, long>(new SelectWorkspaceParameters(Resources.SetDefaultWorkspace, defaultWorkspace.Id));

            if (selectedWorkspaceId == currentUser.DefaultWorkspaceId)
            {
                return;
            }

            await interactorFactory.UpdateDefaultWorkspace(selectedWorkspaceId).Execute();

            syncManager.InitiatePushSync();
        }
Пример #12
0
        public static async Task Create(this DeeplinkCreateTimeEntryParameters parameters, IInteractorFactory interactorFactory)
        {
            var workspaceId = parameters.WorkspaceId;

            if (!workspaceId.HasValue)
            {
                var defaultWorkspace = await interactorFactory.GetDefaultWorkspace().Execute();

                workspaceId = defaultWorkspace.Id;
            }

            var startTime = parameters.StartTime;

            if (!startTime.HasValue)
            {
                return;
            }

            var stopTime = parameters.StopTime;
            var duration = parameters.Duration;

            if (!duration.HasValue && !stopTime.HasValue)
            {
                return;
            }

            if (!duration.HasValue)
            {
                duration = stopTime.Value - startTime.Value;
            }

            var description = parameters.Description ?? string.Empty;
            var projectId   = parameters.ProjectId;
            var taskId      = parameters.TaskId;
            var tagIds      = parameters.TagIds;
            var isBillable  = parameters.IsBillable ?? false;
            var source      = parameters.StartSource ?? TimeEntryStartOrigin.Deeplink;

            var prototype = description.AsTimeEntryPrototype(startTime.Value, workspaceId.Value, duration, projectId, taskId, tagIds, isBillable);
            await interactorFactory.CreateTimeEntry(prototype, source).Execute();
        }
Пример #13
0
        public static async Task Start(this DeeplinkStartTimeEntryParameters parameters, IInteractorFactory interactorFactory, ITimeService timeService)
        {
            var workspaceId = parameters.WorkspaceId;

            if (!workspaceId.HasValue)
            {
                var defaultWorkspace = await interactorFactory.GetDefaultWorkspace().Execute();

                workspaceId = defaultWorkspace.Id;
            }

            var description = parameters.Description ?? string.Empty;
            var startTime   = parameters.StartTime ?? timeService.CurrentDateTime;
            var projectId   = parameters.ProjectId;
            var taskId      = parameters.TaskId;
            var tagIds      = parameters.TagIds;
            var isBillable  = parameters.IsBillable ?? false;
            var source      = parameters.Source ?? TimeEntryStartOrigin.Deeplink;

            var prototype = description.AsTimeEntryPrototype(startTime, workspaceId.Value, null, projectId, taskId, tagIds, isBillable);
            await interactorFactory.CreateTimeEntry(prototype, source).Execute();
        }
Пример #14
0
        public override async Task Initialize()
        {
            navigationFromStartTimeEntryViewModelStopwatch = stopwatchProvider.Get(MeasuredOperation.OpenCreateProjectViewFromStartTimeEntryView);
            stopwatchProvider.Remove(MeasuredOperation.OpenCreateProjectViewFromStartTimeEntryView);

            var defaultWorkspace = await interactorFactory.GetDefaultWorkspace()
                                   .TrackException <InvalidOperationException, IThreadSafeWorkspace>("EditProjectViewModel.Initialize")
                                   .Execute();

            var allWorkspaces = await interactorFactory.GetAllWorkspaces().Execute();

            var workspace = defaultWorkspace.IsEligibleForProjectCreation()
                ? defaultWorkspace
                : allWorkspaces.First(ws => ws.IsEligibleForProjectCreation());

            areCustomColorsEnabled = await interactorFactory.AreCustomColorsEnabledForWorkspace(workspace.Id).Execute();

            workspaceId   = initialWorkspaceId = workspace.Id;
            WorkspaceName = workspace.Name;

            await setupNameAlreadyTakenError();
        }
Пример #15
0
        public SettingsViewModel(
            UserAgent userAgent,
            IMailService mailService,
            ITogglDataSource dataSource,
            IDialogService dialogService,
            IUserPreferences userPreferences,
            IFeedbackService feedbackService,
            IAnalyticsService analyticsService,
            IInteractorFactory interactorFactory,
            IPlatformConstants platformConstants,
            IOnboardingStorage onboardingStorage,
            IMvxNavigationService navigationService)
        {
            Ensure.Argument.IsNotNull(userAgent, nameof(userAgent));
            Ensure.Argument.IsNotNull(dataSource, nameof(dataSource));
            Ensure.Argument.IsNotNull(mailService, nameof(mailService));
            Ensure.Argument.IsNotNull(dialogService, nameof(dialogService));
            Ensure.Argument.IsNotNull(userPreferences, nameof(userPreferences));
            Ensure.Argument.IsNotNull(feedbackService, nameof(feedbackService));
            Ensure.Argument.IsNotNull(analyticsService, nameof(analyticsService));
            Ensure.Argument.IsNotNull(onboardingStorage, nameof(onboardingStorage));
            Ensure.Argument.IsNotNull(interactorFactory, nameof(interactorFactory));
            Ensure.Argument.IsNotNull(navigationService, nameof(navigationService));
            Ensure.Argument.IsNotNull(platformConstants, nameof(platformConstants));

            this.userAgent         = userAgent;
            this.dataSource        = dataSource;
            this.mailService       = mailService;
            this.dialogService     = dialogService;
            this.userPreferences   = userPreferences;
            this.feedbackService   = feedbackService;
            this.analyticsService  = analyticsService;
            this.interactorFactory = interactorFactory;
            this.navigationService = navigationService;
            this.platformConstants = platformConstants;
            this.onboardingStorage = onboardingStorage;

            IsSynced = dataSource.SyncManager.ProgressObservable.SelectMany(checkSynced);

            IsRunningSync =
                dataSource.SyncManager
                .ProgressObservable
                .Select(isRunningSync);

            Name =
                dataSource.User.Current
                .Select(user => user.Fullname)
                .DistinctUntilChanged();

            Email =
                dataSource.User.Current
                .Select(user => user.Email.ToString())
                .DistinctUntilChanged();

            IsManualModeEnabled = userPreferences.IsManualModeEnabledObservable;

            WorkspaceName =
                dataSource.User.Current
                .DistinctUntilChanged(user => user.DefaultWorkspaceId)
                .SelectMany(_ => interactorFactory.GetDefaultWorkspace().Execute())
                .Select(workspace => workspace.Name);

            BeginningOfWeek =
                dataSource.User.Current
                .Select(user => user.BeginningOfWeek)
                .DistinctUntilChanged()
                .Select(beginningOfWeek => beginningOfWeek.ToString());

            DateFormat =
                dataSource.Preferences.Current
                .Select(preferences => preferences.DateFormat.Localized)
                .DistinctUntilChanged();

            DurationFormat =
                dataSource.Preferences.Current
                .Select(preferences => preferences.DurationFormat)
                .Select(DurationFormatToString.Convert)
                .DistinctUntilChanged();

            UseTwentyFourHourFormat =
                dataSource.Preferences.Current
                .Select(preferences => preferences.TimeOfDayFormat.IsTwentyFourHoursFormat)
                .DistinctUntilChanged();

            UserAvatar =
                dataSource.User.Current
                .Select(user => user.ImageUrl)
                .DistinctUntilChanged()
                .SelectMany(url => interactorFactory.GetUserAvatar(url).Execute());

            Workspaces =
                dataSource.User.Current
                .DistinctUntilChanged(user => user.DefaultWorkspaceId)
                .SelectMany(user => interactorFactory
                            .GetAllWorkspaces()
                            .Execute()
                            .Select(selectableWorkspacesFromWorkspaces(user))
                            );

            LoggingOut = loggingOutSubject.AsObservable();

            dataSource.User.Current
            .Subscribe(user => currentUser = user)
            .DisposedBy(disposeBag);

            dataSource.Preferences.Current
            .Subscribe(preferences => currentPreferences = preferences)
            .DisposedBy(disposeBag);

            IsRunningSync
            .Subscribe(isSyncing => this.isSyncing = isSyncing)
            .DisposedBy(disposeBag);

            IsFeedbackSuccessViewShowing = isFeedbackSuccessViewShowing.AsObservable();
        }
Пример #16
0
        private async Task openReports()
        {
            var workspace = await interactorFactory.GetDefaultWorkspace().Execute();

            await navigationService.Navigate <ReportsViewModel, long>(workspace.Id);
        }
Пример #17
0
        public SettingsViewModel(
            ITogglDataSource dataSource,
            ISyncManager syncManager,
            IPlatformInfo platformInfo,
            IDialogService dialogService,
            IUserPreferences userPreferences,
            IAnalyticsService analyticsService,
            IUserAccessManager userAccessManager,
            IInteractorFactory interactorFactory,
            IOnboardingStorage onboardingStorage,
            IMvxNavigationService navigationService,
            IPrivateSharedStorageService privateSharedStorageService,
            IIntentDonationService intentDonationService,
            IStopwatchProvider stopwatchProvider,
            IRxActionFactory rxActionFactory,
            IPermissionsService permissionsService,
            ISchedulerProvider schedulerProvider)
        {
            Ensure.Argument.IsNotNull(dataSource, nameof(dataSource));
            Ensure.Argument.IsNotNull(syncManager, nameof(syncManager));
            Ensure.Argument.IsNotNull(platformInfo, nameof(platformInfo));
            Ensure.Argument.IsNotNull(dialogService, nameof(dialogService));
            Ensure.Argument.IsNotNull(userPreferences, nameof(userPreferences));
            Ensure.Argument.IsNotNull(analyticsService, nameof(analyticsService));
            Ensure.Argument.IsNotNull(onboardingStorage, nameof(onboardingStorage));
            Ensure.Argument.IsNotNull(interactorFactory, nameof(interactorFactory));
            Ensure.Argument.IsNotNull(navigationService, nameof(navigationService));
            Ensure.Argument.IsNotNull(userAccessManager, nameof(userAccessManager));
            Ensure.Argument.IsNotNull(privateSharedStorageService, nameof(privateSharedStorageService));
            Ensure.Argument.IsNotNull(intentDonationService, nameof(intentDonationService));
            Ensure.Argument.IsNotNull(stopwatchProvider, nameof(stopwatchProvider));
            Ensure.Argument.IsNotNull(rxActionFactory, nameof(rxActionFactory));
            Ensure.Argument.IsNotNull(permissionsService, nameof(permissionsService));
            Ensure.Argument.IsNotNull(schedulerProvider, nameof(schedulerProvider));

            this.dataSource                  = dataSource;
            this.syncManager                 = syncManager;
            this.platformInfo                = platformInfo;
            this.dialogService               = dialogService;
            this.userPreferences             = userPreferences;
            this.rxActionFactory             = rxActionFactory;
            this.analyticsService            = analyticsService;
            this.interactorFactory           = interactorFactory;
            this.navigationService           = navigationService;
            this.userAccessManager           = userAccessManager;
            this.onboardingStorage           = onboardingStorage;
            this.stopwatchProvider           = stopwatchProvider;
            this.intentDonationService       = intentDonationService;
            this.privateSharedStorageService = privateSharedStorageService;
            this.rxActionFactory             = rxActionFactory;
            this.schedulerProvider           = schedulerProvider;
            this.permissionsService          = permissionsService;

            IsSynced =
                syncManager.ProgressObservable
                .SelectMany(checkSynced)
                .AsDriver(schedulerProvider);

            IsRunningSync =
                syncManager.ProgressObservable
                .Select(isRunningSync)
                .AsDriver(schedulerProvider);

            Name =
                dataSource.User.Current
                .Select(user => user.Fullname)
                .DistinctUntilChanged()
                .AsDriver(schedulerProvider);

            Email =
                dataSource.User.Current
                .Select(user => user.Email.ToString())
                .DistinctUntilChanged()
                .AsDriver(schedulerProvider);

            IsManualModeEnabled = userPreferences.IsManualModeEnabledObservable
                                  .AsDriver(schedulerProvider);

            AreRunningTimerNotificationsEnabled = userPreferences.AreRunningTimerNotificationsEnabledObservable
                                                  .AsDriver(schedulerProvider);

            AreStoppedTimerNotificationsEnabled = userPreferences.AreStoppedTimerNotificationsEnabledObservable
                                                  .AsDriver(schedulerProvider);

            WorkspaceName =
                dataSource.User.Current
                .DistinctUntilChanged(user => user.DefaultWorkspaceId)
                .SelectMany(_ => interactorFactory.GetDefaultWorkspace()
                            .TrackException <InvalidOperationException, IThreadSafeWorkspace>("SettingsViewModel.constructor")
                            .Execute()
                            )
                .Select(workspace => workspace.Name)
                .AsDriver(schedulerProvider);

            BeginningOfWeek =
                dataSource.User.Current
                .Select(user => user.BeginningOfWeek)
                .DistinctUntilChanged()
                .Select(beginningOfWeek => beginningOfWeek.ToString())
                .AsDriver(schedulerProvider);

            DateFormat =
                dataSource.Preferences.Current
                .Select(preferences => preferences.DateFormat.Localized)
                .DistinctUntilChanged()
                .AsDriver(schedulerProvider);

            DurationFormat =
                dataSource.Preferences.Current
                .Select(preferences => preferences.DurationFormat)
                .Select(DurationFormatToString.Convert)
                .DistinctUntilChanged()
                .AsDriver(schedulerProvider);

            UseTwentyFourHourFormat =
                dataSource.Preferences.Current
                .Select(preferences => preferences.TimeOfDayFormat.IsTwentyFourHoursFormat)
                .DistinctUntilChanged()
                .AsDriver(schedulerProvider);

            IsGroupingTimeEntries =
                dataSource.Preferences.Current
                .Select(preferences => preferences.CollapseTimeEntries)
                .DistinctUntilChanged()
                .AsDriver(false, schedulerProvider);

            IsCalendarSmartRemindersVisible = calendarPermissionGranted.AsObservable()
                                              .CombineLatest(userPreferences.EnabledCalendars.Select(ids => ids.Any()), CommonFunctions.And);

            CalendarSmartReminders = userPreferences.CalendarNotificationsSettings()
                                     .Select(s => s.Title())
                                     .DistinctUntilChanged();

            UserAvatar =
                dataSource.User.Current
                .Select(user => user.ImageUrl)
                .DistinctUntilChanged()
                .SelectMany(url => interactorFactory.GetUserAvatar(url).Execute())
                .AsDriver(schedulerProvider)
                .Where(avatar => avatar != null);

            Workspaces =
                dataSource.User.Current
                .DistinctUntilChanged(user => user.DefaultWorkspaceId)
                .SelectMany(user => interactorFactory
                            .GetAllWorkspaces()
                            .Execute()
                            .Select(selectableWorkspacesFromWorkspaces(user))
                            )
                .AsDriver(schedulerProvider);

            LoggingOut = loggingOutSubject.AsObservable()
                         .AsDriver(schedulerProvider);

            dataSource.User.Current
            .Subscribe(user => currentUser = user)
            .DisposedBy(disposeBag);

            dataSource.Preferences.Current
            .Subscribe(preferences => currentPreferences = preferences)
            .DisposedBy(disposeBag);

            IsRunningSync
            .Subscribe(isSyncing => this.isSyncing = isSyncing)
            .DisposedBy(disposeBag);

            IsFeedbackSuccessViewShowing = isFeedbackSuccessViewShowing.AsObservable()
                                           .AsDriver(schedulerProvider);

            OpenCalendarSettings         = rxActionFactory.FromAsync(openCalendarSettings);
            OpenCalendarSmartReminders   = rxActionFactory.FromAsync(openCalendarSmartReminders);
            OpenNotificationSettings     = rxActionFactory.FromAsync(openNotificationSettings);
            ToggleTwentyFourHourSettings = rxActionFactory.FromAsync(toggleUseTwentyFourHourClock);
            OpenHelpView              = rxActionFactory.FromAsync(openHelpView);
            TryLogout                 = rxActionFactory.FromAsync(tryLogout);
            OpenAboutView             = rxActionFactory.FromAsync(openAboutView);
            SubmitFeedback            = rxActionFactory.FromAsync(submitFeedback);
            SelectDateFormat          = rxActionFactory.FromAsync(selectDateFormat);
            PickDefaultWorkspace      = rxActionFactory.FromAsync(pickDefaultWorkspace);
            SelectDurationFormat      = rxActionFactory.FromAsync(selectDurationFormat);
            SelectBeginningOfWeek     = rxActionFactory.FromAsync(selectBeginningOfWeek);
            ToggleTimeEntriesGrouping = rxActionFactory.FromAsync(toggleTimeEntriesGrouping);
            SelectDefaultWorkspace    = rxActionFactory.FromAsync <SelectableWorkspaceViewModel>(selectDefaultWorkspace);
            Close = rxActionFactory.FromAsync(close);
        }
Пример #18
0
        public EditProjectViewModel(
            ITogglDataSource dataSource,
            IRxActionFactory rxActionFactory,
            IInteractorFactory interactorFactory,
            ISchedulerProvider schedulerProvider,
            INavigationService navigationService)
            : base(navigationService)
        {
            Ensure.Argument.IsNotNull(dataSource, nameof(dataSource));
            Ensure.Argument.IsNotNull(rxActionFactory, nameof(rxActionFactory));
            Ensure.Argument.IsNotNull(interactorFactory, nameof(interactorFactory));
            Ensure.Argument.IsNotNull(schedulerProvider, nameof(schedulerProvider));

            this.dataSource        = dataSource;
            this.interactorFactory = interactorFactory;

            Name      = new BehaviorRelay <string>("");
            IsPrivate = new BehaviorRelay <bool>(true);

            PickColor     = rxActionFactory.FromObservable <Color>(pickColor);
            PickClient    = rxActionFactory.FromObservable <IThreadSafeClient>(pickClient);
            PickWorkspace = rxActionFactory.FromObservable <IThreadSafeWorkspace>(pickWorkspace);

            var initialWorkspaceObservable = interactorFactory
                                             .GetDefaultWorkspace()
                                             .TrackException <InvalidOperationException, IThreadSafeWorkspace>("EditProjectViewModel.Initialize")
                                             .Execute()
                                             .SelectMany(defaultWorkspaceOrWorkspaceEligibleForProjectCreation)
                                             .Do(initialWorkspace => initialWorkspaceId = initialWorkspace.Id);

            currentWorkspace = initialWorkspaceObservable
                               .Merge(PickWorkspace.Elements)
                               .ShareReplay(1);

            currentClient = currentWorkspace
                            .SelectValue((IThreadSafeClient)null)
                            .Merge(PickClient.Elements)
                            .ShareReplay(1);

            WorkspaceName = currentWorkspace
                            .Select(w => w.Name)
                            .DistinctUntilChanged()
                            .AsDriver(schedulerProvider);

            CanCreatePublicProjects = currentWorkspace
                                      .Select(w => w.Admin)
                                      .DoIf(isAdmin => !isAdmin, _ => IsPrivate.Accept(true))
                                      .DistinctUntilChanged()
                                      .AsDriver(schedulerProvider);

            var clientName = currentClient
                             .Select(client => client?.Name ?? "")
                             .DistinctUntilChanged();

            ClientName = clientName
                         .AsDriver(schedulerProvider);

            Color = PickColor.Elements
                    .StartWith(getRandomColor())
                    .Merge(currentWorkspace
                           .SelectMany(customColorIsEnabled)
                           .SelectMany(customColorsAreAvailable => customColorsAreAvailable
                        ? Observable.Empty <Color>()
                        : Color.FirstAsync().Select(randomColorIfNotDefault)))
                    .DistinctUntilChanged()
                    .AsDriver(schedulerProvider);

            var saveEnabledObservable = Name.Select(checkNameValidity);

            var projectOrClientNameChanged = Observable
                                             .Merge(clientName.SelectUnit(), Name.SelectUnit());

            Save            = rxActionFactory.FromObservable(done, saveEnabledObservable);
            ToggleIsPrivate = rxActionFactory.FromAction(toggleIsPrivate);

            Error = Save.Errors
                    .Select(e => e.Message)
                    .Merge(projectOrClientNameChanged.SelectValue(string.Empty))
                    .AsDriver(schedulerProvider);

            IObservable <IThreadSafeWorkspace> defaultWorkspaceOrWorkspaceEligibleForProjectCreation(IThreadSafeWorkspace defaultWorkspace)
            => defaultWorkspace.IsEligibleForProjectCreation()
                    ? Observable.Return(defaultWorkspace)
                    : interactorFactory.GetAllWorkspaces().Execute()
            .Select(allWorkspaces => allWorkspaces.First(ws => ws.IsEligibleForProjectCreation()));

            IObservable <bool> customColorIsEnabled(IThreadSafeWorkspace workspace)
            => interactorFactory
            .AreCustomColorsEnabledForWorkspace(workspace.Id)
            .Execute();

            Color getRandomColor()
            {
                var randomColorIndex = random.Next(0, Helper.Colors.DefaultProjectColors.Length);

                return(Helper.Colors.DefaultProjectColors[randomColorIndex]);
            }

            Color randomColorIfNotDefault(Color lastColor)
            {
                var hex = lastColor.ToHexString();

                if (DefaultProjectColors.Any(defaultColor => defaultColor == hex))
                {
                    return(lastColor);
                }

                return(getRandomColor());
            }

            bool checkNameValidity(string name)
            => !string.IsNullOrWhiteSpace(name) &&
            name.LengthInBytes() <= Constants.MaxProjectNameLengthInBytes;
        }
        public override async Task Initialize(StartTimeEntryParameters parameter)
        {
            await base.Initialize(parameter);

            this.parameter = parameter;
            startTime      = parameter.StartTime;
            duration       = parameter.Duration;

            PlaceholderText = parameter.PlaceholderText;
            if (!string.IsNullOrEmpty(parameter.EntryDescription))
            {
                initialParameters = parameter;
            }

            displayedTime.Accept(duration ?? TimeSpan.Zero);

            timeService.CurrentDateTimeObservable
            .Where(_ => isRunning)
            .Subscribe(currentTime => displayedTime.Accept(currentTime - startTime))
            .DisposedBy(disposeBag);

            defaultWorkspace = await interactorFactory.GetDefaultWorkspace()
                               .TrackException <InvalidOperationException, IThreadSafeWorkspace>("StartTimeEntryViewModel.Initialize")
                               .Execute();

            canCreateProjectsInWorkspace =
                await interactorFactory.GetAllWorkspaces().Execute().Select(allWorkspaces =>
                                                                            allWorkspaces.Any(ws => ws.IsEligibleForProjectCreation()));

            if (initialParameters != null)
            {
                var spans = new List <ISpan>();
                spans.Add(new TextSpan(initialParameters.EntryDescription));
                if (initialParameters.ProjectId != null)
                {
                    try
                    {
                        var project = await interactorFactory.GetProjectById((long)initialParameters.ProjectId).Execute();

                        spans.Add(new ProjectSpan(project));
                    }
                    catch
                    {
                        // Intentionally left blank
                    }
                }
                if (initialParameters.TagIds != null)
                {
                    try
                    {
                        var tags = initialParameters.TagIds.ToObservable()
                                   .SelectMany <long, IThreadSafeTag>(tagId => interactorFactory.GetTagById(tagId).Execute())
                                   .ToEnumerable();
                        spans.AddRange(tags.Select(tag => new TagSpan(tag)));
                    }
                    catch
                    {
                        // Intentionally left blank
                    }
                }

                textFieldInfo.Accept(textFieldInfo.Value.ReplaceSpans(spans.ToImmutableList()));
            }
            else
            {
                textFieldInfo.Accept(Autocomplete.TextFieldInfo.Empty(parameter?.WorkspaceId ?? defaultWorkspace.Id));
            }

            hasAnyTags     = (await DataSource.Tags.GetAll()).Any();
            hasAnyProjects = (await DataSource.Projects.GetAll()).Any();
        }
Пример #20
0
        public SettingsViewModel(
            ITogglDataSource dataSource,
            ISyncManager syncManager,
            IPlatformInfo platformInfo,
            IUserPreferences userPreferences,
            IAnalyticsService analyticsService,
            IInteractorFactory interactorFactory,
            IOnboardingStorage onboardingStorage,
            INavigationService navigationService,
            IRxActionFactory rxActionFactory,
            IPermissionsChecker permissionsChecker,
            ISchedulerProvider schedulerProvider)
            : base(navigationService)
        {
            Ensure.Argument.IsNotNull(dataSource, nameof(dataSource));
            Ensure.Argument.IsNotNull(syncManager, nameof(syncManager));
            Ensure.Argument.IsNotNull(platformInfo, nameof(platformInfo));
            Ensure.Argument.IsNotNull(userPreferences, nameof(userPreferences));
            Ensure.Argument.IsNotNull(analyticsService, nameof(analyticsService));
            Ensure.Argument.IsNotNull(onboardingStorage, nameof(onboardingStorage));
            Ensure.Argument.IsNotNull(interactorFactory, nameof(interactorFactory));
            Ensure.Argument.IsNotNull(rxActionFactory, nameof(rxActionFactory));
            Ensure.Argument.IsNotNull(permissionsChecker, nameof(permissionsChecker));
            Ensure.Argument.IsNotNull(schedulerProvider, nameof(schedulerProvider));

            this.dataSource         = dataSource;
            this.syncManager        = syncManager;
            this.platformInfo       = platformInfo;
            this.userPreferences    = userPreferences;
            this.analyticsService   = analyticsService;
            this.interactorFactory  = interactorFactory;
            this.onboardingStorage  = onboardingStorage;
            this.permissionsChecker = permissionsChecker;

            IsSynced =
                syncManager.ProgressObservable
                .SelectMany(checkSynced)
                .AsDriver(schedulerProvider);

            IsRunningSync =
                syncManager.ProgressObservable
                .Select(isRunningSync)
                .AsDriver(schedulerProvider);

            Name =
                dataSource.User.Current
                .Select(user => user.Fullname)
                .DistinctUntilChanged()
                .AsDriver(schedulerProvider);

            Email =
                dataSource.User.Current
                .Select(user => user.Email.ToString())
                .DistinctUntilChanged()
                .AsDriver(schedulerProvider);

            IsManualModeEnabled = userPreferences.IsManualModeEnabledObservable
                                  .AsDriver(schedulerProvider);

            AreRunningTimerNotificationsEnabled = userPreferences.AreRunningTimerNotificationsEnabledObservable
                                                  .AsDriver(schedulerProvider);

            AreStoppedTimerNotificationsEnabled = userPreferences.AreStoppedTimerNotificationsEnabledObservable
                                                  .AsDriver(schedulerProvider);

            WorkspaceName =
                dataSource.User.Current
                .DistinctUntilChanged(user => user.DefaultWorkspaceId)
                .SelectMany(_ => interactorFactory.GetDefaultWorkspace()
                            .TrackException <InvalidOperationException, IThreadSafeWorkspace>("SettingsViewModel.constructor")
                            .Execute()
                            )
                .Select(workspace => workspace.Name)
                .AsDriver(schedulerProvider);

            BeginningOfWeek =
                dataSource.User.Current
                .Select(user => user.BeginningOfWeek)
                .DistinctUntilChanged()
                .Select(beginningOfWeek => beginningOfWeek.ToLocalizedString())
                .AsDriver(schedulerProvider);

            DateFormat =
                dataSource.Preferences.Current
                .Select(preferences => preferences.DateFormat.Localized)
                .DistinctUntilChanged()
                .AsDriver(schedulerProvider);

            DurationFormat =
                dataSource.Preferences.Current
                .Select(preferences => preferences.DurationFormat.ToFormattedString())
                .DistinctUntilChanged()
                .AsDriver(schedulerProvider);

            UseTwentyFourHourFormat =
                dataSource.Preferences.Current
                .Select(preferences => preferences.TimeOfDayFormat.IsTwentyFourHoursFormat)
                .DistinctUntilChanged()
                .AsDriver(schedulerProvider);

            IsGroupingTimeEntries =
                dataSource.Preferences.Current
                .Select(preferences => preferences.CollapseTimeEntries)
                .DistinctUntilChanged()
                .AsDriver(false, schedulerProvider);

            IsCalendarSmartRemindersVisible = calendarPermissionGranted.AsObservable()
                                              .CombineLatest(userPreferences.EnabledCalendars.Select(ids => ids.Any()), CommonFunctions.And);

            CalendarSmartReminders = userPreferences.CalendarNotificationsSettings()
                                     .Select(s => s.Title())
                                     .DistinctUntilChanged();

            LoggingOut = loggingOutSubject.AsObservable()
                         .AsDriver(schedulerProvider);

            PresentableSyncStatus combineStatuses(bool synced, bool syncing, bool loggingOut)
            {
                if (loggingOut)
                {
                    return(PresentableSyncStatus.LoggingOut);
                }

                return(syncing ? PresentableSyncStatus.Syncing : PresentableSyncStatus.Synced);
            }

            CurrentSyncStatus = Observable.CombineLatest(
                IsSynced,
                IsRunningSync,
                LoggingOut.SelectValue(true).StartWith(false),
                combineStatuses);

            dataSource.User.Current
            .Subscribe(user => currentUser = user)
            .DisposedBy(disposeBag);

            dataSource.Preferences.Current
            .Subscribe(preferences => currentPreferences = preferences)
            .DisposedBy(disposeBag);

            IsRunningSync
            .Subscribe(isSyncing => this.isSyncing = isSyncing)
            .DisposedBy(disposeBag);

            IsFeedbackSuccessViewShowing = isFeedbackSuccessViewShowing.AsObservable()
                                           .AsDriver(schedulerProvider);

            SwipeActionsEnabled = userPreferences.SwipeActionsEnabled
                                  .AsDriver(schedulerProvider);

            OpenCalendarSettings         = rxActionFactory.FromAsync(openCalendarSettings);
            OpenCalendarSmartReminders   = rxActionFactory.FromAsync(openCalendarSmartReminders);
            OpenNotificationSettings     = rxActionFactory.FromAsync(openNotificationSettings);
            ToggleTwentyFourHourSettings = rxActionFactory.FromAsync(toggleUseTwentyFourHourClock);
            OpenHelpView              = rxActionFactory.FromAsync(openHelpView);
            TryLogout                 = rxActionFactory.FromAsync(tryLogout);
            OpenAboutView             = rxActionFactory.FromAsync(openAboutView);
            OpenSiriShortcuts         = rxActionFactory.FromAsync(openSiriShorcuts);
            OpenSiriWorkflows         = rxActionFactory.FromAsync(openSiriWorkflows);
            SubmitFeedback            = rxActionFactory.FromAsync(submitFeedback);
            SelectDateFormat          = rxActionFactory.FromAsync(selectDateFormat);
            PickDefaultWorkspace      = rxActionFactory.FromAsync(pickDefaultWorkspace);
            SelectDurationFormat      = rxActionFactory.FromAsync(selectDurationFormat);
            SelectBeginningOfWeek     = rxActionFactory.FromAsync(selectBeginningOfWeek);
            ToggleTimeEntriesGrouping = rxActionFactory.FromAsync(toggleTimeEntriesGrouping);
            ToggleManualMode          = rxActionFactory.FromAction(toggleManualMode);
            ToggleSwipeActions        = rxActionFactory.FromAction(toggleSwipeActions);
        }