public override void AwakeFromNib() { base.AwakeFromNib(); this.DelayBind(() => { var colorConverter = new MvxRGBValueConverter(); var durationCombiner = new DurationValueCombiner(); var bindingSet = this.CreateBindingSet <ReportsLegendViewCell, ChartSegment>(); //Text bindingSet.Bind(ProjectLabel).To(vm => vm.ProjectName); bindingSet.Bind(PercentageLabel) .For(v => v.Text) .ByCombining("Format", "'{0:0.00}%'", nameof(ChartSegment.Percentage)); bindingSet.Bind(TotalTimeLabel) .ByCombining(durationCombiner, vm => vm.TrackedTime, vm => vm.DurationFormat); // Color bindingSet.Bind(ProjectLabel) .For(v => v.TextColor) .To(vm => vm.Color) .WithConversion(colorConverter); bindingSet.Bind(CircleView) .For(v => v.BackgroundColor) .To(vm => vm.Color) .WithConversion(colorConverter); bindingSet.Apply(); }); }
public override void AwakeFromNib() { base.AwakeFromNib(); ContentView.BackgroundColor = UIColor.White; DurationLabel.Font = DurationLabel.Font.GetMonospacedDigitFont(); this.DelayBind(() => { var visibilityConverter = new MvxVisibilityValueConverter(); var durationCombiner = new DurationValueCombiner(); var dateTitleConverter = new DateToTitleStringValueConverter(); var bindingSet = this.CreateBindingSet <TimeEntriesLogHeaderViewCell, TimeEntryViewModelCollection>(); //Text bindingSet.Bind(DateLabel) .To(vm => vm.Date) .WithConversion(dateTitleConverter); bindingSet.Bind(DurationLabel) .ByCombining(durationCombiner, vm => vm.TotalTime, vm => vm.DurationFormat); bindingSet.Apply(); }); }
public override void AwakeFromNib() { base.AwakeFromNib(); var templateImage = TotalDurationGraph.Image.ImageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate); TotalDurationGraph.Image = templateImage; var durationCombiner = new DurationValueCombiner(); this.DelayBind(() => { var bindingSet = this.CreateBindingSet <ReportsHeaderView, ReportsViewModel>(); //Text bindingSet.Bind(BillablePercentageLabel) .For(v => v.AttributedText) .To(vm => vm.BillablePercentage) .WithConversion(new ReportPercentageLabelValueConverter()); bindingSet.Bind(TotalDurationLabel) .For(v => v.Text) .ByCombining(durationCombiner, vm => vm.TotalTime, vm => vm.DurationFormat); //Loading chart bindingSet.Bind(LoadingPieChartView) .For(v => v.BindVisible()) .To(vm => vm.IsLoading); //Pretty stuff bindingSet.Bind(PieChartView) .For(v => v.Segments) .To(vm => vm.Segments); bindingSet.Bind(BillablePercentageView) .For(v => v.Percentage) .To(vm => vm.BillablePercentage); bindingSet.Bind(TotalDurationGraph) .For(v => v.TintColor) .To(vm => vm.TotalTimeIsZero) .WithConversion(new BoolToConstantValueConverter <UIColor>( Color.Reports.Disabled.ToNativeColor(), Color.Reports.TotalTimeActivated.ToNativeColor() )); //Visibility bindingSet.Bind(EmptyStateView) .For(v => v.BindVisible()) .To(vm => vm.ShowEmptyState); bindingSet.Apply(); }); }
public override void ViewDidLoad() { base.ViewDidLoad(); setupDismissingByTappingOnBackground(); prepareViews(); var durationCombiner = new DurationValueCombiner(); var dateCombiner = new DateTimeOffsetDateFormatValueCombiner(TimeZoneInfo.Local); var timeCombiner = new DateTimeOffsetTimeFormatValueCombiner(TimeZoneInfo.Local); var visibilityConverter = new MvxVisibilityValueConverter(); var invertedBoolConverter = new BoolToConstantValueConverter <bool>(false, true); var inverterVisibilityConverter = new MvxInvertedVisibilityValueConverter(); var projectTaskClientCombiner = new ProjectTaskClientValueCombiner( ProjectTaskClientLabel.Font.CapHeight, Color.EditTimeEntry.ClientText.ToNativeColor(), false ); var stopRunningTimeEntryAndEditDurationForStoppedConverter = new BoolToConstantValueConverter <IMvxCommand>( ViewModel.StopCommand, ViewModel.EditDurationCommand); var bindingSet = this.CreateBindingSet <EditTimeEntryViewController, EditTimeEntryViewModel>(); //Error message view bindingSet.Bind(ErrorMessageLabel) .For(v => v.Text) .To(vm => vm.SyncErrorMessage); bindingSet.Bind(ErrorView) .For(v => v.BindTap()) .To(vm => vm.DismissSyncErrorMessageCommand); bindingSet.Bind(ErrorView) .For(v => v.BindVisible()) .To(vm => vm.SyncErrorMessageVisible) .WithConversion(inverterVisibilityConverter); //Text bindingSet.Bind(DescriptionTextView) .For(v => v.RemainingLength) .To(vm => vm.DescriptionRemainingLength); bindingSet.Bind(DescriptionTextView) .For(v => v.BindText()) .To(vm => vm.Description); bindingSet.Bind(BillableSwitch) .For(v => v.BindAnimatedOn()) .To(vm => vm.Billable); bindingSet.Bind(DurationLabel) .ByCombining(durationCombiner, vm => vm.Duration, vm => vm.DurationFormat); bindingSet.Bind(ProjectTaskClientLabel) .For(v => v.AttributedText) .ByCombining(projectTaskClientCombiner, v => v.Project, v => v.Task, v => v.Client, v => v.ProjectColor); bindingSet.Bind(StartDateLabel) .ByCombining(dateCombiner, vm => vm.StartTime, vm => vm.DateFormat); bindingSet.Bind(StartTimeLabel) .ByCombining(timeCombiner, vm => vm.StartTime, vm => vm.TimeFormat); bindingSet.Bind(EndTimeLabel) .ByCombining(timeCombiner, vm => vm.StopTime, vm => vm.TimeFormat); //Commands bindingSet.Bind(CloseButton).To(vm => vm.CloseCommand); bindingSet.Bind(DeleteButton).To(vm => vm.DeleteCommand); bindingSet.Bind(ConfirmButton).To(vm => vm.ConfirmCommand); bindingSet.Bind(DurationView) .For(v => v.BindTap()) .To(vm => vm.EditDurationCommand); bindingSet.Bind(StartTimeView) .For(v => v.BindTap()) .To(vm => vm.EditDurationCommand); bindingSet.Bind(StopButton) .To(vm => vm.StopCommand); bindingSet.Bind(EndTimeView) .For(v => v.BindTap()) .To(vm => vm.IsTimeEntryRunning) .WithConversion(stopRunningTimeEntryAndEditDurationForStoppedConverter); bindingSet.Bind(ProjectTaskClientLabel) .For(v => v.BindTap()) .To(vm => vm.SelectProjectCommand); bindingSet.Bind(AddProjectAndTaskView) .For(v => v.BindTap()) .To(vm => vm.SelectProjectCommand); bindingSet.Bind(StartDateView) .For(v => v.BindTap()) .To(vm => vm.SelectStartDateCommand); bindingSet.Bind(TagsTextView) .For(v => v.BindTap()) .To(vm => vm.SelectTagsCommand); bindingSet.Bind(AddTagsView) .For(v => v.BindTap()) .To(vm => vm.SelectTagsCommand); bindingSet.Bind(BillableView) .For(v => v.BindTap()) .To(vm => vm.ToggleBillableCommand); //End time and the stop button visibility bindingSet.Bind(StopButton) .For(v => v.BindVisible()) .To(vm => vm.IsTimeEntryRunning) .WithConversion(inverterVisibilityConverter); bindingSet.Bind(EndTimeLabel) .For(v => v.BindVisible()) .To(vm => vm.IsTimeEntryRunning) .WithConversion(visibilityConverter); //Project visibility bindingSet.Bind(AddProjectAndTaskView) .For(v => v.BindVisible()) .To(vm => vm.Project) .WithConversion(visibilityConverter); bindingSet.Bind(ProjectTaskClientLabel) .For(v => v.BindVisible()) .To(vm => vm.Project) .WithConversion(inverterVisibilityConverter); //Tags visibility bindingSet.Bind(AddTagsView) .For(v => v.BindVisible()) .To(vm => vm.HasTags) .WithConversion(visibilityConverter); bindingSet.Bind(TagsTextView) .For(v => v.BindVisible()) .To(vm => vm.HasTags) .WithConversion(inverterVisibilityConverter); //Confirm button enabled bindingSet.Bind(ConfirmButton) .For(v => v.Enabled) .To(vm => vm.DescriptionLimitExceeded) .WithConversion(invertedBoolConverter); bindingSet.Bind(ConfirmButton) .For(v => v.Alpha) .To(vm => vm.DescriptionLimitExceeded) .WithConversion(new BoolToConstantValueConverter <nfloat>(0.5f, 1)); bindingSet.Bind(BillableView) .For(v => v.BindVisibility()) .To(vm => vm.IsBillableAvailable) .WithConversion(visibilityConverter); bindingSet.Apply(); }
public override void ViewDidLoad() { base.ViewDidLoad(); TitleLabel.Text = Resources.Edit; BillableLabel.Text = Resources.Billable; StartDateDescriptionLabel.Text = Resources.Startdate; DurationDescriptionLabel.Text = Resources.Duration; StartDescriptionLabel.Text = Resources.Start; EndDescriptionLabel.Text = Resources.End; ErrorMessageTitleLabel.Text = Resources.Oops; AddProjectTaskLabel.Text = Resources.AddProjectTask; CategorizeWithProjectsLabel.Text = Resources.CategorizeYourTimeWithProjects; AddTagsLabel.Text = Resources.AddTags; DeleteButton.SetTitle(Resources.Delete, UIControlState.Normal); ConfirmButton.SetTitle(Resources.ConfirmChanges, UIControlState.Normal); prepareViews(); prepareOnboarding(); contentSizeChangedDisposable = ScrollViewContent.AddObserver(boundsKey, NSKeyValueObservingOptions.New, onContentSizeChanged); var durationCombiner = new DurationValueCombiner(); var dateCombiner = new DateTimeOffsetDateFormatValueCombiner(TimeZoneInfo.Local); var timeCombiner = new DateTimeOffsetTimeFormatValueCombiner(TimeZoneInfo.Local); var visibilityConverter = new MvxVisibilityValueConverter(); var invertedBoolConverter = new BoolToConstantValueConverter <bool>(false, true); var inverterVisibilityConverter = new MvxInvertedVisibilityValueConverter(); var projectTaskClientCombiner = new ProjectTaskClientValueCombiner( ProjectTaskClientLabel.Font.CapHeight, Color.EditTimeEntry.ClientText.ToNativeColor(), false ); var stopRunningTimeEntryAndSelectStopTimeForStoppedConverter = new BoolToConstantValueConverter <IMvxCommand>( ViewModel.StopCommand, ViewModel.SelectStopTimeCommand); var isInaccessibleTextColorConverter = new BoolToConstantValueConverter <UIColor>( Color.Common.Disabled.ToNativeColor(), Color.Common.TextColor.ToNativeColor() ); var showTagsCombiner = new ShowTagsValueCombiner(); var bindingSet = this.CreateBindingSet <EditTimeEntryViewController, EditTimeEntryViewModel>(); //Error message view bindingSet.Bind(ErrorMessageLabel) .For(v => v.Text) .To(vm => vm.SyncErrorMessage); bindingSet.Bind(ErrorView) .For(v => v.BindTap()) .To(vm => vm.DismissSyncErrorMessageCommand); bindingSet.Bind(ErrorView) .For(v => v.BindVisible()) .To(vm => vm.SyncErrorMessageVisible) .WithConversion(inverterVisibilityConverter); //Text bindingSet.Bind(RemainingCharacterCount) .To(vm => vm.DescriptionRemainingLength); bindingSet.Bind(RemainingCharacterCount) .For(v => v.BindVisible()) .To(vm => vm.DescriptionLimitExceeded); bindingSet.Bind(DescriptionTextView) .For(v => v.BindText()) .To(vm => vm.Description); bindingSet.Bind(DescriptionTextView) .For(v => v.BindDidBecomeFirstResponder()) .To(vm => vm.StartEditingDescriptionCommand); bindingSet.Bind(DurationLabel) .ByCombining(durationCombiner, vm => vm.Duration, vm => vm.DurationFormat); bindingSet.Bind(ProjectTaskClientLabel) .For(v => v.AttributedText) .ByCombining(projectTaskClientCombiner, v => v.Project, v => v.Task, v => v.Client, v => v.ProjectColor); bindingSet.Bind(StartDateLabel) .ByCombining(dateCombiner, vm => vm.StartTime, vm => vm.DateFormat); bindingSet.Bind(StartTimeLabel) .ByCombining(timeCombiner, vm => vm.StartTime, vm => vm.TimeFormat); bindingSet.Bind(EndTimeLabel) .ByCombining(timeCombiner, vm => vm.StopTime, vm => vm.TimeFormat); //Commands bindingSet.Bind(CloseButton).To(vm => vm.CloseCommand); bindingSet.Bind(DeleteButton).To(vm => vm.DeleteCommand); bindingSet.Bind(ConfirmButton).To(vm => vm.SaveCommand); bindingSet.Bind(DurationView) .For(v => v.BindTap()) .To(vm => vm.SelectDurationCommand); bindingSet.Bind(StartTimeView) .For(v => v.BindTap()) .To(vm => vm.SelectStartTimeCommand); bindingSet.Bind(StopButton) .To(vm => vm.StopCommand); bindingSet.Bind(EndTimeView) .For(v => v.BindTap()) .To(vm => vm.IsTimeEntryRunning) .WithConversion(stopRunningTimeEntryAndSelectStopTimeForStoppedConverter); bindingSet.Bind(ProjectTaskClientLabel) .For(v => v.BindTap()) .To(vm => vm.SelectProjectCommand); bindingSet.Bind(AddProjectAndTaskView) .For(v => v.BindTap()) .To(vm => vm.SelectProjectCommand); bindingSet.Bind(StartDateView) .For(v => v.BindTap()) .To(vm => vm.SelectStartDateCommand); bindingSet.Bind(TagsTextView) .For(v => v.BindTap()) .To(vm => vm.SelectTagsCommand); bindingSet.Bind(AddTagsView) .For(v => v.BindTap()) .To(vm => vm.SelectTagsCommand); bindingSet.Bind(BillableSwitch) .For(v => v.BindValueChanged()) .To(vm => vm.ToggleBillableCommand); //End time and the stop button visibility bindingSet.Bind(StopButton) .For(v => v.BindVisible()) .To(vm => vm.IsTimeEntryRunning) .WithConversion(inverterVisibilityConverter); bindingSet.Bind(EndTimeLabel) .For(v => v.BindVisible()) .To(vm => vm.IsTimeEntryRunning) .WithConversion(visibilityConverter); //Project visibility bindingSet.Bind(AddProjectAndTaskView) .For(v => v.BindVisible()) .To(vm => vm.Project) .WithConversion(visibilityConverter); bindingSet.Bind(ProjectTaskClientLabel) .For(v => v.BindVisible()) .To(vm => vm.Project) .WithConversion(inverterVisibilityConverter); //Tags visibility bindingSet.Bind(AddTagsView) .For(v => v.BindVisible()) .To(vm => vm.HasTags) .WithConversion(visibilityConverter); bindingSet.Bind(TagsTextView) .For(v => v.BindVisible()) .To(vm => vm.HasTags) .WithConversion(inverterVisibilityConverter); //Confirm button enabled bindingSet.Bind(ConfirmButton) .For(v => v.Enabled) .To(vm => vm.DescriptionLimitExceeded) .WithConversion(invertedBoolConverter); bindingSet.Bind(ConfirmButton) .For(v => v.Alpha) .To(vm => vm.DescriptionLimitExceeded) .WithConversion(new BoolToConstantValueConverter <nfloat>(0.5f, 1)); bindingSet.Bind(BillableView) .For(v => v.BindVisibility()) .To(vm => vm.IsBillableAvailable) .WithConversion(visibilityConverter); //Regarding inaccessible entries getLabelsToChangeColorWhenEditingInaccessibleEntry().ForEach(createTextColorBindingForInaccessibleEntries); bindingSet.Bind(DescriptionTextView) .For(v => v.TextColor) .To(vm => vm.IsInaccessible) .WithConversion(isInaccessibleTextColorConverter); bindingSet.Bind(DescriptionTextView) .For(v => v.UserInteractionEnabled) .To(vm => vm.IsInaccessible) .WithConversion(invertedBoolConverter); bindingSet.Bind(BillableSwitch) .For(v => v.Enabled) .To(vm => vm.IsInaccessible) .WithConversion(invertedBoolConverter); bindingSet.Bind(TagsContainerView) .For(v => v.Hidden) .ByCombining(showTagsCombiner, vm => vm.IsInaccessible, vm => vm.HasTags) .WithConversion(invertedBoolConverter); bindingSet.Bind(TagsSeparator) .For(v => v.Hidden) .ByCombining(showTagsCombiner, vm => vm.IsInaccessible, vm => vm.HasTags) .WithConversion(invertedBoolConverter); bindingSet.Apply(); void createTextColorBindingForInaccessibleEntries(UILabel label) { bindingSet.Bind(label) .For(v => v.TextColor) .To(vm => vm.IsInaccessible) .WithConversion(isInaccessibleTextColorConverter); } }
public override void AwakeFromNib() { base.AwakeFromNib(); var templateImage = TotalDurationGraph.Image.ImageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate); TotalDurationGraph.Image = templateImage; prepareViews(); var colorConverter = new BoolToConstantValueConverter <UIColor>( Color.Reports.Disabled.ToNativeColor(), Color.Reports.TotalTimeActivated.ToNativeColor() ); var durationCombiner = new DurationValueCombiner(); this.DelayBind(() => { var bindingSet = this.CreateBindingSet <ReportsHeaderView, ReportsViewModel>(); //Text bindingSet.Bind(BillablePercentageLabel) .For(v => v.AttributedText) .To(vm => vm.BillablePercentage) .WithConversion(new ReportPercentageLabelValueConverter()); bindingSet.Bind(TotalDurationLabel) .For(v => v.Text) .ByCombining(durationCombiner, vm => vm.TotalTime, vm => vm.DurationFormat); //Loading chart bindingSet.Bind(LoadingPieChartView) .For(v => v.BindVisibilityWithFade()) .To(vm => vm.IsLoading); bindingSet.Bind(LoadingCardView) .For(v => v.BindVisibilityWithFade()) .To(vm => vm.IsLoading); //Pretty stuff bindingSet.Bind(PieChartView) .For(v => v.Segments) .To(vm => vm.GroupedSegments); bindingSet.Bind(BillablePercentageView) .For(v => v.Percentage) .To(vm => vm.BillablePercentage); bindingSet.Bind(TotalDurationGraph) .For(v => v.TintColor) .To(vm => vm.TotalTimeIsZero) .WithConversion(colorConverter); bindingSet.Bind(TotalDurationLabel) .For(v => v.TextColor) .To(vm => vm.TotalTimeIsZero) .WithConversion(colorConverter); // Bar chart if (ViewModel == null) { throw new InvalidOperationException($"The {nameof(ViewModel)} value must be set for {nameof(ReportsHeaderView)} before defining bindings."); } ViewModel.WorkspaceHasBillableFeatureEnabled .Subscribe(ColorsLegendContainerView.Rx().IsVisible()) .DisposedBy(disposeBag); ViewModel.StartDate .CombineLatest( ViewModel.BarChartViewModel.DateFormat, (startDate, format) => startDate.ToString(format.Short)) .Subscribe(StartDateLabel.Rx().Text()) .DisposedBy(disposeBag); ViewModel.EndDate .CombineLatest( ViewModel.BarChartViewModel.DateFormat, (endDate, format) => endDate.ToString(format.Short)) .Subscribe(EndDateLabel.Rx().Text()) .DisposedBy(disposeBag); ViewModel.BarChartViewModel.MaximumHoursPerBar .Select(hours => $"{hours} h") .Subscribe(MaximumHoursLabel.Rx().Text()) .DisposedBy(disposeBag); ViewModel.BarChartViewModel.MaximumHoursPerBar .Select(hours => $"{hours/2} h") .Subscribe(HalfHoursLabel.Rx().Text()) .DisposedBy(disposeBag); ViewModel.BarChartViewModel.HorizontalLegend .Where(legend => legend == null) .Subscribe((DateTimeOffset[] _) => { HorizontalLegendStackView.Subviews.ForEach(subview => subview.RemoveFromSuperview()); StartDateLabel.Hidden = false; EndDateLabel.Hidden = false; }) .DisposedBy(disposeBag); ViewModel.BarChartViewModel.HorizontalLegend .Where(legend => legend != null) .CombineLatest(ViewModel.BarChartViewModel.DateFormat, createHorizontalLegendLabels) .Do(_ => { StartDateLabel.Hidden = true; EndDateLabel.Hidden = true; }) .Subscribe(HorizontalLegendStackView.Rx().ArrangedViews()) .DisposedBy(disposeBag); ViewModel.BarChartViewModel.Bars .Select(createBarViews) .Subscribe(BarsStackView.Rx().ArrangedViews()) .DisposedBy(disposeBag); var spacingObservable = ViewModel.BarChartViewModel.Bars .CombineLatest(updateLayout, (bars, _) => bars) .Select(bars => BarsStackView.Frame.Width / bars.Length * barChartSpacingProportion); spacingObservable .Subscribe(BarsStackView.Rx().Spacing()) .DisposedBy(disposeBag); spacingObservable .Subscribe(HorizontalLegendStackView.Rx().Spacing()) .DisposedBy(disposeBag); ViewModel.IsLoadingObservable .Select(CommonFunctions.Invert) .Subscribe(BarChartContainerView.Rx().IsVisible()) .DisposedBy(disposeBag); //Visibility bindingSet.Bind(EmptyStateView) .For(v => v.BindVisible()) .To(vm => vm.ShowEmptyState); bindingSet.Apply(); }); }
public override void ViewDidLoad() { base.ViewDidLoad(); AddProjectBubbleLabel.Text = Resources.AddProjectBubbleText; prepareViews(); prepareOnboarding(); var source = new StartTimeEntryTableViewSource(SuggestionsTableView); SuggestionsTableView.Source = source; source.ToggleTasksCommand = new MvxCommand <ProjectSuggestion>(toggleTaskSuggestions); var invertedVisibilityConverter = new MvxInvertedVisibilityValueConverter(); var invertedBoolConverter = new BoolToConstantValueConverter <bool>(false, true); var buttonColorConverter = new BoolToConstantValueConverter <UIColor>( Color.StartTimeEntry.ActiveButton.ToNativeColor(), Color.StartTimeEntry.InactiveButton.ToNativeColor() ); var durationCombiner = new DurationValueCombiner(); var bindingSet = this.CreateBindingSet <StartTimeEntryViewController, StartTimeEntryViewModel>(); //TableView bindingSet.Bind(source) .For(v => v.ObservableCollection) .To(vm => vm.Suggestions); bindingSet.Bind(source) .For(v => v.UseGrouping) .To(vm => vm.UseGrouping); bindingSet.Bind(source) .For(v => v.SelectSuggestionCommand) .To(vm => vm.SelectSuggestionCommand); bindingSet.Bind(source) .For(v => v.CreateCommand) .To(vm => vm.CreateCommand); bindingSet.Bind(source) .For(v => v.IsSuggestingProjects) .To(vm => vm.IsSuggestingProjects); bindingSet.Bind(source) .For(v => v.Text) .To(vm => vm.CurrentQuery); bindingSet.Bind(source) .For(v => v.SuggestCreation) .To(vm => vm.SuggestCreation); bindingSet.Bind(source) .For(v => v.ShouldShowNoTagsInfoMessage) .To(vm => vm.ShouldShowNoTagsInfoMessage); bindingSet.Bind(source) .For(v => v.ShouldShowNoProjectsInfoMessage) .To(vm => vm.ShouldShowNoProjectsInfoMessage); //Text bindingSet.Bind(TimeInput) .For(v => v.Duration) .To(vm => vm.DisplayedTime) .Mode(MvxBindingMode.OneWayToSource); bindingSet.Bind(TimeLabel) .For(v => v.Text) .ByCombining(durationCombiner, vm => vm.DisplayedTime, vm => vm.DisplayedTimeFormat); bindingSet.Bind(Placeholder) .To(vm => vm.PlaceholderText); //Buttons bindingSet.Bind(TagsButton) .For(v => v.TintColor) .To(vm => vm.IsSuggestingTags) .WithConversion(buttonColorConverter); bindingSet.Bind(BillableButton) .For(v => v.TintColor) .To(vm => vm.IsBillable) .WithConversion(buttonColorConverter); bindingSet.Bind(ProjectsButton) .For(v => v.TintColor) .To(vm => vm.IsSuggestingProjects) .WithConversion(buttonColorConverter); //Visibility bindingSet.Bind(BillableButtonWidthConstraint) .For(v => v.Constant) .To(vm => vm.IsBillableAvailable) .WithConversion(new BoolToConstantValueConverter <nfloat>(42, 0)); //Commands bindingSet.Bind(DoneButton).To(vm => vm.DoneCommand); bindingSet.Bind(CloseButton).To(vm => vm.BackCommand); bindingSet.Bind(BillableButton).To(vm => vm.ToggleBillableCommand); bindingSet.Bind(StartDateButton).To(vm => vm.SetStartDateCommand); bindingSet.Bind(DateTimeButton).To(vm => vm.ChangeTimeCommand); bindingSet.Bind(TagsButton).To(vm => vm.ToggleTagSuggestionsCommand); bindingSet.Bind(ProjectsButton).To(vm => vm.ToggleProjectSuggestionsCommand); bindingSet.Apply(); // Reactive ViewModel.TextFieldInfoObservable .Subscribe(onTextFieldInfo) .DisposedBy(DisposeBag); DescriptionTextView.Rx().AttributedText() .Select(attributedString => attributedString.Length == 0) .Subscribe(isDescriptionEmptySubject) .DisposedBy(DisposeBag); DescriptionTextView.Rx().AttributedText() .CombineLatest(DescriptionTextView.Rx().CursorPosition(), (text, _) => text) .Where(_ => !isUpdatingDescriptionField) .SubscribeOn(ThreadPoolScheduler.Instance) .Do(updatePlaceholder) .Select(text => text.AsImmutableSpans((int)DescriptionTextView.SelectedRange.Location)) .ObserveOn(SynchronizationContext.Current) .Subscribe(async info => await ViewModel.OnTextFieldInfoFromView(info)) .DisposedBy(DisposeBag); source.TableRenderCallback = () => { ViewModel.StopSuggestionsRenderingStopwatch(); }; }
public override void ViewDidLoad() { base.ViewDidLoad(); startTimeChangingSubscription = ViewModel.StartTimeChanging.Subscribe(startTimeChanging); setupDismissingByTappingOnBackground(); prepareViews(); var durationCombiner = new DurationValueCombiner(); var timeCombiner = new DateTimeOffsetTimeFormatValueCombiner(TimeZoneInfo.Local); var dateCombiner = new DateTimeOffsetDateFormatValueCombiner(TimeZoneInfo.Local, useLongFormat: false); var timeFormatToLocaleConverter = new TimeFormatToLocaleValueConverter(); var inverseBoolConverter = new BoolToConstantValueConverter <bool>(false, true); var editedTimeLabelColorConverter = new BoolToConstantValueConverter <UIColor>( Color.EditDuration.EditedTime.ToNativeColor(), Color.EditDuration.NotEditedTime.ToNativeColor()); var bindingSet = this.CreateBindingSet <EditDurationViewController, EditDurationViewModel>(); //Commands bindingSet.Bind(SaveButton).To(vm => vm.SaveCommand); bindingSet.Bind(CloseButton).To(vm => vm.CloseCommand); //Start and stop date/time bindingSet.Bind(StartTimeLabel) .ByCombining(timeCombiner, vm => vm.StartTime, vm => vm.TimeFormat); bindingSet.Bind(StartDateLabel) .ByCombining(dateCombiner, vm => vm.StartTime, vm => vm.DateFormat); bindingSet.Bind(EndTimeLabel) .ByCombining(timeCombiner, vm => vm.StopTime, vm => vm.TimeFormat); bindingSet.Bind(EndDateLabel) .ByCombining(dateCombiner, vm => vm.StopTime, vm => vm.DateFormat); //Editing start and end time bindingSet.Bind(StartView) .For(v => v.BindTap()) .To(vm => vm.EditStartTimeCommand); bindingSet.Bind(EndView) .For(v => v.BindTap()) .To(vm => vm.EditStopTimeCommand); bindingSet.Bind(SetEndButton) .For(v => v.BindVisibility()) .To(vm => vm.IsRunning) .WithConversion(inverseBoolConverter); bindingSet.Bind(SetEndButton) .To(vm => vm.EditStopTimeCommand); //Visiblity bindingSet.Bind(EndTimeLabel) .For(v => v.BindVisibility()) .To(vm => vm.IsRunning); bindingSet.Bind(EndDateLabel) .For(v => v.BindVisibility()) .To(vm => vm.IsRunning); //Stard and end colors bindingSet.Bind(StartTimeLabel) .For(v => v.TextColor) .To(vm => vm.IsEditingStartTime) .WithConversion(editedTimeLabelColorConverter); bindingSet.Bind(StartDateLabel) .For(v => v.TextColor) .To(vm => vm.IsEditingStartTime) .WithConversion(editedTimeLabelColorConverter); bindingSet.Bind(EndTimeLabel) .For(v => v.TextColor) .To(vm => vm.IsEditingStopTime) .WithConversion(editedTimeLabelColorConverter); bindingSet.Bind(EndDateLabel) .For(v => v.TextColor) .To(vm => vm.IsEditingStopTime) .WithConversion(editedTimeLabelColorConverter); //Date picker bindingSet.Bind(DatePickerContainer) .For(v => v.BindAnimatedVisibility()) .To(vm => vm.IsEditingTime); bindingSet.Bind(DatePicker) .For(v => v.BindDateTimeOffset()) .To(vm => vm.EditedTime); bindingSet.Bind(DatePicker) .For(v => v.MaximumDate) .To(vm => vm.MaximumDateTime); bindingSet.Bind(DatePicker) .For(v => v.MinimumDate) .To(vm => vm.MinimumDateTime); bindingSet.Bind(DatePicker) .For(v => v.Locale) .To(vm => vm.TimeFormat) .WithConversion(timeFormatToLocaleConverter); //The wheel bindingSet.Bind(DurationInput) .For(v => v.UserInteractionEnabled) .To(vm => vm.IsEditingTime) .WithConversion(inverseBoolConverter); bindingSet.Bind(DurationInput) .For(v => v.Duration) .To(vm => vm.Duration); bindingSet.Bind(DurationInput) .For(v => v.FormattedDuration) .ByCombining(durationCombiner, vm => vm.Duration, vm => vm.DurationFormat); bindingSet.Bind(WheelView) .For(v => v.UserInteractionEnabled) .To(vm => vm.IsEditingTime) .WithConversion(inverseBoolConverter); bindingSet.Bind(WheelView) .For(v => v.MaximumStartTime) .To(vm => vm.MaximumStartTime); bindingSet.Bind(WheelView) .For(v => v.MinimumStartTime) .To(vm => vm.MinimumStartTime); bindingSet.Bind(WheelView) .For(v => v.MaximumEndTime) .To(vm => vm.MaximumStopTime); bindingSet.Bind(WheelView) .For(v => v.MinimumEndTime) .To(vm => vm.MinimumStopTime); bindingSet.Bind(WheelView) .For(v => v.StartTime) .To(vm => vm.StartTime); bindingSet.Bind(WheelView) .For(v => v.EndTime) .To(vm => vm.StopTime); bindingSet.Bind(WheelView) .For(v => v.IsRunning) .To(vm => vm.IsRunning); bindingSet.Apply(); }
public override void ViewDidLoad() { base.ViewDidLoad(); prepareViews(); prepareOnboarding(); setupTableViewHeader(); var visibilityConverter = new MvxVisibilityValueConverter(); var projectTaskClientCombiner = new ProjectTaskClientValueCombiner( CurrentTimeEntryProjectTaskClientLabel.Font.CapHeight, Color.Main.CurrentTimeEntryClientColor.ToNativeColor(), true ); var startTimeEntryButtonManualModeIconConverter = new BoolToConstantValueConverter <UIImage>( UIImage.FromBundle("manualIcon"), UIImage.FromBundle("playIcon") ); var durationCombiner = new DurationValueCombiner(); var bindingSet = this.CreateBindingSet <MainViewController, MainViewModel>(); // Table view tableViewSource = new TimeEntriesLogViewSource(ViewModel.TimeEntries, TimeEntriesLogViewCell.Identifier); TimeEntriesLogTableView .Rx() .Bind(tableViewSource) .DisposedBy(disposeBag); this.Bind(tableViewSource.FirstCell, f => { onFirstTimeEntryChanged(f); firstTimeEntryCell = f; }); this.Bind(tableViewSource.ScrollOffset, onTableScroll); var continueTimeEntry = Observable.Merge( tableViewSource.ContinueTap, tableViewSource.SwipeToContinue ); this.Bind(continueTimeEntry, ViewModel.ContinueTimeEntry); this.Bind(tableViewSource.SwipeToDelete, ViewModel.TimeEntriesViewModel.DelayDeleteTimeEntry); this.Bind(tableViewSource.ItemSelected, ViewModel.SelectTimeEntry); this.Bind(ViewModel.TimeEntriesViewModel.ShouldShowUndo, toggleUndoDeletion); tableViewSource.SwipeToContinue .VoidSubscribe(() => { swipeRightStep.Dismiss(); }) .DisposedBy(disposeBag); tableViewSource.SwipeToDelete .VoidSubscribe(() => { swipeLeftStep.Dismiss(); }) .DisposedBy(disposeBag); // Refresh Control var refreshControl = new RefreshControl(ViewModel.SyncProgressState, tableViewSource); this.Bind(refreshControl.Refresh, ViewModel.RefreshAction); TimeEntriesLogTableView.CustomRefreshControl = refreshControl; //Commands bindingSet.Bind(settingsButton).To(vm => vm.OpenSettingsCommand); bindingSet.Bind(StopTimeEntryButton).To(vm => vm.StopTimeEntryCommand); bindingSet.Bind(StartTimeEntryButton).To(vm => vm.StartTimeEntryCommand); bindingSet.Bind(EditTimeEntryButton).To(vm => vm.EditTimeEntryCommand); bindingSet.Bind(syncFailuresButton).To(vm => vm.OpenSyncFailuresCommand); bindingSet.Bind(CurrentTimeEntryCard) .For(v => v.BindTap()) .To(vm => vm.EditTimeEntryCommand); bindingSet.Bind(suggestionsView) .For(v => v.SuggestionTappedCommad) .To(vm => vm.SuggestionsViewModel.StartTimeEntryCommand); bindingSet.Bind(StartTimeEntryButton) .For(v => v.BindLongPress()) .To(vm => vm.AlternativeStartTimeEntryCommand); //Visibility var shouldWelcomeBack = ViewModel.ShouldShowWelcomeBack; this.Bind(ViewModel.ShouldShowEmptyState, visible => emptyStateView.Hidden = !visible); this.Bind(shouldWelcomeBack, WelcomeBackView.Rx().IsVisible()); this.Bind(shouldWelcomeBack, spiderContainerView.Rx().IsVisible()); this.Bind(shouldWelcomeBack, visible => { if (visible) { spiderBroView.Show(); } else { spiderBroView.Hide(); } }); //Text bindingSet.Bind(CurrentTimeEntryDescriptionLabel).To(vm => vm.CurrentTimeEntryDescription); bindingSet.Bind(CurrentTimeEntryElapsedTimeLabel) .ByCombining(durationCombiner, vm => vm.CurrentTimeEntryElapsedTime, vm => vm.CurrentTimeEntryElapsedTimeFormat); bindingSet.Bind(CurrentTimeEntryProjectTaskClientLabel) .For(v => v.AttributedText) .ByCombining(projectTaskClientCombiner, v => v.CurrentTimeEntryProject, v => v.CurrentTimeEntryTask, v => v.CurrentTimeEntryClient, v => v.CurrentTimeEntryProjectColor); //The start button bindingSet.Bind(StartTimeEntryButton) .For(v => v.BindImage()) .To(vm => vm.IsInManualMode) .WithConversion(startTimeEntryButtonManualModeIconConverter); //The sync failures button bindingSet.Bind(syncFailuresButton) .For(v => v.BindVisibility()) .To(vm => vm.NumberOfSyncFailures) .WithConversion(visibilityConverter); bindingSet.Apply(); this.Bind(ViewModel.RatingViewModel.IsFeedbackSuccessViewShowing, SendFeedbackSuccessView.Rx().AnimatedIsVisible()); this.BindVoid(SendFeedbackSuccessView.Rx().Tap(), ViewModel.RatingViewModel.CloseFeedbackSuccessView); ViewModel.ShouldReloadTimeEntryLog .VoidSubscribe(reload) .DisposedBy(disposeBag); View.SetNeedsLayout(); View.LayoutIfNeeded(); NSNotificationCenter.DefaultCenter.AddObserver(UIApplication.DidBecomeActiveNotification, onApplicationDidBecomeActive); }
public override void ViewDidLoad() { base.ViewDidLoad(); startTimeChangingSubscription = ViewModel.StartTimeChanging.Subscribe(startTimeChanging); prepareViews(); var durationCombiner = new DurationValueCombiner(); var timeCombiner = new DateTimeOffsetTimeFormatValueCombiner(TimeZoneInfo.Local); var dateCombiner = new DateTimeOffsetDateFormatValueCombiner(TimeZoneInfo.Local, useLongFormat: false); var timeFormatToLocaleConverter = new TimeFormatToLocaleValueConverter(); var inverseBoolConverter = new BoolToConstantValueConverter <bool>(false, true); var editedTimeLabelColorConverter = new BoolToConstantValueConverter <UIColor>( Color.EditDuration.EditedTime.ToNativeColor(), Color.EditDuration.NotEditedTime.ToNativeColor()); var bindingSet = this.CreateBindingSet <EditDurationViewController, EditDurationViewModel>(); //Commands bindingSet.Bind(SaveButton).To(vm => vm.SaveCommand); bindingSet.Bind(CloseButton).To(vm => vm.CloseCommand); //Start and stop date/time bindingSet.Bind(StartTimeLabel) .ByCombining(timeCombiner, vm => vm.StartTime, vm => vm.TimeFormat); bindingSet.Bind(StartDateLabel) .ByCombining(dateCombiner, vm => vm.StartTime, vm => vm.DateFormat); bindingSet.Bind(EndTimeLabel) .ByCombining(timeCombiner, vm => vm.StopTime, vm => vm.TimeFormat); bindingSet.Bind(EndDateLabel) .ByCombining(dateCombiner, vm => vm.StopTime, vm => vm.DateFormat); //Editing start and end time bindingSet.Bind(StartView) .For(v => v.BindTap()) .To(vm => vm.EditStartTimeCommand); bindingSet.Bind(EndView) .For(v => v.BindTap()) .To(vm => vm.EditStopTimeCommand); bindingSet.Bind(SetEndButton) .For(v => v.BindVisibility()) .To(vm => vm.IsRunning) .WithConversion(inverseBoolConverter); bindingSet.Bind(SetEndButton) .To(vm => vm.EditStopTimeCommand); //Visibility bindingSet.Bind(EndTimeLabel) .For(v => v.BindVisibility()) .To(vm => vm.IsRunning); bindingSet.Bind(EndDateLabel) .For(v => v.BindVisibility()) .To(vm => vm.IsRunning); //Stard and end colors bindingSet.Bind(StartTimeLabel) .For(v => v.TextColor) .To(vm => vm.IsEditingStartTime) .WithConversion(editedTimeLabelColorConverter); bindingSet.Bind(StartDateLabel) .For(v => v.TextColor) .To(vm => vm.IsEditingStartTime) .WithConversion(editedTimeLabelColorConverter); bindingSet.Bind(EndTimeLabel) .For(v => v.TextColor) .To(vm => vm.IsEditingStopTime) .WithConversion(editedTimeLabelColorConverter); bindingSet.Bind(EndDateLabel) .For(v => v.TextColor) .To(vm => vm.IsEditingStopTime) .WithConversion(editedTimeLabelColorConverter); //Date picker bindingSet.Bind(DatePickerContainer) .For(v => v.BindAnimatedVisibility()) .To(vm => vm.IsEditingTime); bindingSet.Bind(DatePicker) .For(v => v.BindDateTimeOffset()) .To(vm => vm.EditedTime); bindingSet.Bind(DatePicker) .For(v => v.MaximumDate) .To(vm => vm.MaximumDateTime); bindingSet.Bind(DatePicker) .For(v => v.MinimumDate) .To(vm => vm.MinimumDateTime); bindingSet.Bind(DatePicker) .For(v => v.Locale) .To(vm => vm.TimeFormat) .WithConversion(timeFormatToLocaleConverter); //The wheel bindingSet.Bind(DurationInput) .For(v => v.UserInteractionEnabled) .To(vm => vm.IsEditingTime) .WithConversion(inverseBoolConverter); bindingSet.Bind(DurationInput) .For(v => v.Duration) .To(vm => vm.Duration); bindingSet.Bind(DurationInput) .For(v => v.FormattedDuration) .ByCombining(durationCombiner, vm => vm.Duration, vm => vm.DurationFormat); bindingSet.Bind(WheelView) .For(v => v.UserInteractionEnabled) .To(vm => vm.IsEditingTime) .WithConversion(inverseBoolConverter); bindingSet.Bind(WheelView) .For(v => v.MaximumStartTime) .To(vm => vm.MaximumStartTime); bindingSet.Bind(WheelView) .For(v => v.MinimumStartTime) .To(vm => vm.MinimumStartTime); bindingSet.Bind(WheelView) .For(v => v.MaximumEndTime) .To(vm => vm.MaximumStopTime); bindingSet.Bind(WheelView) .For(v => v.MinimumEndTime) .To(vm => vm.MinimumStopTime); bindingSet.Bind(WheelView) .For(v => v.StartTime) .To(vm => vm.StartTime); bindingSet.Bind(WheelView) .For(v => v.EndTime) .To(vm => vm.StopTime); bindingSet.Bind(WheelView) .For(v => v.IsRunning) .To(vm => vm.IsRunning); bindingSet.Apply(); // Interaction observables for analytics var editingStart = Observable.Merge( StartView.Rx().Tap().Select(true), EndView.Rx().Tap().Select(false) ); var dateComponentChanged = DatePicker.Rx().DateComponent() .WithLatestFrom(editingStart, (_, isStart) => isStart ? EditTimeSource.BarrelStartDate : EditTimeSource.BarrelStopDate ); var timeComponentChanged = DatePicker.Rx().TimeComponent() .WithLatestFrom(editingStart, (_, isStart) => isStart ? EditTimeSource.BarrelStartTime : EditTimeSource.BarrelStopTime ); var durationInputChanged = Observable .FromEventPattern(e => DurationInput.DurationChanged += e, e => DurationInput.DurationChanged -= e) .Select(EditTimeSource.NumpadDuration); Observable.Merge( dateComponentChanged, timeComponentChanged, WheelView.TimeEdited, durationInputChanged ) .Distinct() .Subscribe(ViewModel.TimeEditedWithSource) .DisposedBy(disposeBag); }
public override void AwakeFromNib() { base.AwakeFromNib(); FadeView.FadeRight = true; TimeLabel.Font = TimeLabel.Font.GetMonospacedDigitFont(); ContinueButton.TouchUpInside += onContinueButtonTap; this.DelayBind(() => { var colorConverter = new MvxRGBValueConverter(); var visibilityConverter = new MvxVisibilityValueConverter(); var durationCombiner = new DurationValueCombiner(); var invertedVisibilityConverter = new MvxInvertedVisibilityValueConverter(); var projectTaskClientCombiner = new ProjectTaskClientValueCombiner( ProjectTaskClientLabel.Font.CapHeight, Color.TimeEntriesLog.ClientColor.ToNativeColor(), true ); var descriptionTopDistanceValueConverter = new BoolToConstantValueConverter <nfloat>(hasProjectDistance, noProjectDistance); var bindingSet = this.CreateBindingSet <TimeEntriesLogViewCell, TimeEntryViewModel>(); //Text bindingSet.Bind(DescriptionLabel).To(vm => vm.Description); bindingSet.Bind(ProjectTaskClientLabel) .For(v => v.AttributedText) .ByCombining(projectTaskClientCombiner, v => v.ProjectName, v => v.TaskName, v => v.ClientName, v => v.ProjectColor); bindingSet.Bind(TimeLabel) .ByCombining(durationCombiner, vm => vm.Duration, vm => vm.DurationFormat); //Visibility bindingSet.Bind(DescriptionTopDistanceConstraint) .For(v => v.Constant) .To(vm => vm.HasProject) .WithConversion(descriptionTopDistanceValueConverter); bindingSet.Bind(ProjectTaskClientLabel) .For(v => v.BindVisibility()) .To(vm => vm.HasProject) .WithConversion(visibilityConverter); bindingSet.Bind(AddDescriptionLabel) .For(v => v.BindVisibility()) .To(vm => vm.HasDescription) .WithConversion(invertedVisibilityConverter); bindingSet.Bind(AddDescriptionTopDistanceConstraint) .For(v => v.Constant) .To(vm => vm.HasProject) .WithConversion(descriptionTopDistanceValueConverter); bindingSet.Bind(SyncErrorImageView) .For(v => v.BindVisibility()) .To(vm => vm.CanSync) .WithConversion(invertedVisibilityConverter); bindingSet.Bind(UnsyncedImageView) .For(v => v.BindVisibility()) .To(vm => vm.NeedsSync) .WithConversion(visibilityConverter); bindingSet.Bind(ContinueButton) .For(v => v.BindVisibility()) .To(vm => vm.CanSync) .WithConversion(visibilityConverter); bindingSet.Bind(ContinueImageView) .For(v => v.BindVisibility()) .To(vm => vm.CanSync) .WithConversion(visibilityConverter); bindingSet.Apply(); }); }