示例#1
0
        private void setupItemTouchHelper(MainRecyclerAdapter mainAdapter)
        {
            var callback        = new MainRecyclerViewTouchCallback(mainAdapter);
            var itemTouchHelper = new ItemTouchHelper(callback);

            itemTouchHelper.AttachToRecyclerView(mainRecyclerView);
        }
示例#2
0
 private void setupLayoutManager(MainRecyclerAdapter mainAdapter)
 {
     layoutManager = new LinearLayoutManager(this);
     layoutManager.ItemPrefetchEnabled      = true;
     layoutManager.InitialPrefetchItemCount = 4;
     mainRecyclerView.SetLayoutManager(layoutManager);
     mainRecyclerView.SetAdapter(mainAdapter);
 }
示例#3
0
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            SetContentView(Resource.Layout.MainActivity);
            OverridePendingTransition(Resource.Animation.abc_fade_in, Resource.Animation.abc_fade_out);

            InitializeViews();

            SetSupportActionBar(FindViewById <Toolbar>(Resource.Id.Toolbar));
            SupportActionBar.SetDisplayShowHomeEnabled(false);
            SupportActionBar.SetDisplayShowTitleEnabled(false);

            runningEntryCardFrame.Visibility = ViewStates.Invisible;

            this.Bind(ViewModel.IsTimeEntryRunning, onTimeEntryCardVisibilityChanged);
            this.Bind(ViewModel.SyncProgressState, onSyncChanged);

            mainRecyclerAdapter = new MainRecyclerAdapter(ViewModel.TimeEntries)
            {
                SuggestionsViewModel = ViewModel.SuggestionsViewModel
            };

            this.Bind(mainRecyclerAdapter.TimeEntryTaps, ViewModel.SelectTimeEntry.Inputs);
            this.Bind(mainRecyclerAdapter.ContinueTimeEntrySubject, ViewModel.ContinueTimeEntry.Inputs);
            this.Bind(mainRecyclerAdapter.DeleteTimeEntrySubject, ViewModel.TimeEntriesViewModel.DelayDeleteTimeEntry.Inputs);
            this.Bind(ViewModel.TimeEntriesViewModel.ShouldShowUndo, showUndoDeletion);

            this.Bind(ViewModel.SyncProgressState, updateSyncingIndicator);
            this.Bind(refreshLayout.Rx().Refreshed(), ViewModel.RefreshAction);

            setupLayoutManager(mainRecyclerAdapter);

            var mainLogChange = ViewModel
                                .TimeEntries
                                .CollectionChange
                                .ObserveOn(SynchronizationContext.Current);

            this.Bind(mainLogChange, mainRecyclerAdapter.UpdateChange);

            var isTimeEntryRunning = ViewModel
                                     .IsTimeEntryRunning
                                     .ObserveOn(SynchronizationContext.Current);

            this.Bind(isTimeEntryRunning, updateRecyclerViewPadding);

            notificationManager = GetSystemService(NotificationService) as NotificationManager;
            this.BindRunningTimeEntry(notificationManager, ViewModel.CurrentRunningTimeEntry, ViewModel.ShouldShowRunningTimeEntryNotification);
            this.BindIdleTimer(notificationManager, ViewModel.IsTimeEntryRunning, ViewModel.ShouldShowStoppedTimeEntryNotification);
            setupItemTouchHelper(mainRecyclerAdapter);

            this.Bind(ViewModel.TimeEntriesCount, timeEntriesCountSubject);

            ViewModel.ShouldReloadTimeEntryLog
            .VoidSubscribe(reload)
            .DisposedBy(DisposeBag);

            setupOnboardingSteps();
        }
        public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            var view = inflater.Inflate(Resource.Layout.fragment_exhibitlist, container, false);

            recyclerView = (RecyclerView)view.FindViewById(Resource.Id.exhibitListRecyclerView);

            // use a linear layout manager
            RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this.Activity);
            recyclerView.SetLayoutManager(layoutManager);

            //RecycleAdapter
            adapter = new MainRecyclerAdapter(ExhibitSet, GeoLocation, Application.Context);
            recyclerView.SetAdapter(adapter);

            recyclerView.AddOnItemTouchListener(new RecyclerItemClickListener((MainActivity)this.Activity, ExhibitSet));

            // Disable refreshing
            var swipeRefreshLayout = view.FindViewById <SwipeRefreshLayout> (Resource.Id.exhibitListSwipeContainer);

            swipeRefreshLayout.Enabled = false;

            return(view);
        }
示例#5
0
        public override void OnViewCreated(View view, Bundle savedInstanceState)
        {
            base.OnViewCreated(view, savedInstanceState);

            refreshLayout.SetProgressBackgroundColorSchemeResource(Resource.Color.cardBackground);
            refreshLayout.SetColorSchemeResources(new[] { Resource.Color.primaryText });

            stopButton.Rx().BindAction(ViewModel.StopTimeEntry, _ => TimeEntryStopOrigin.Manual).DisposedBy(DisposeBag);

            playButton.Rx().BindAction(ViewModel.StartTimeEntry, _ => true).DisposedBy(DisposeBag);
            playButton.Rx().BindAction(ViewModel.StartTimeEntry, _ => false, ButtonEventType.LongPress).DisposedBy(DisposeBag);

            runningEntryCardFrame.Rx().Tap()
            .WithLatestFrom(ViewModel.CurrentRunningTimeEntry,
                            (_, te) => new EditTimeEntryInfo(RunningTimeEntryCard, te.Id))
            .Subscribe(ViewModel.SelectTimeEntry.Inputs)
            .DisposedBy(DisposeBag);

            ViewModel.ElapsedTime
            .Subscribe(timeEntryCardTimerLabel.Rx().TextObserver())
            .DisposedBy(DisposeBag);

            ViewModel.CurrentRunningTimeEntry
            .Select(te => te?.Description ?? "")
            .Subscribe(timeEntryCardDescriptionLabel.Rx().TextObserver())
            .DisposedBy(DisposeBag);

            ViewModel.CurrentRunningTimeEntry
            .Select(te => string.IsNullOrWhiteSpace(te?.Description))
            .Subscribe(timeEntryCardAddDescriptionLabel.Rx().IsVisible())
            .DisposedBy(DisposeBag);

            ViewModel.CurrentRunningTimeEntry
            .Select(te => string.IsNullOrWhiteSpace(te?.Description))
            .Invert()
            .Subscribe(timeEntryCardDescriptionLabel.Rx().IsVisible())
            .DisposedBy(DisposeBag);

            ViewModel.CurrentRunningTimeEntry
            .Select(CreateProjectClientTaskLabel)
            .Subscribe(timeEntryCardProjectClientTaskLabel.Rx().TextFormattedObserver())
            .DisposedBy(DisposeBag);

            var projectVisibilityObservable = ViewModel.CurrentRunningTimeEntry
                                              .Select(te => te?.Project != null);

            projectVisibilityObservable
            .Subscribe(timeEntryCardProjectClientTaskLabel.Rx().IsVisible())
            .DisposedBy(DisposeBag);

            projectVisibilityObservable
            .Subscribe(timeEntryCardDotContainer.Rx().IsVisible())
            .DisposedBy(DisposeBag);

            var projectColorObservable = ViewModel.CurrentRunningTimeEntry
                                         .Select(te => te?.Project?.Color ?? "#000000")
                                         .Select(Color.ParseColor);

            projectColorObservable
            .Subscribe(timeEntryCardDotView.Rx().DrawableColor())
            .DisposedBy(DisposeBag);

            addDrawable  = ContextCompat.GetDrawable(Context, Resource.Drawable.add_white);
            playDrawable = ContextCompat.GetDrawable(Context, Resource.Drawable.play_white);

            ViewModel.IsInManualMode
            .Select(isManualMode => isManualMode ? addDrawable : playDrawable)
            .Subscribe(playButton.SetDrawableImageSafe)
            .DisposedBy(DisposeBag);

            ViewModel.IsTimeEntryRunning
            .Subscribe(onTimeEntryCardVisibilityChanged)
            .DisposedBy(DisposeBag);

            ViewModel.SyncProgressState
            .Subscribe(onSyncChanged)
            .DisposedBy(DisposeBag);

            mainRecyclerAdapter = new MainRecyclerAdapter(Context, ViewModel.TimeService)
            {
                SuggestionsViewModel = ViewModel.SuggestionsViewModel,
                RatingViewModel      = ViewModel.RatingViewModel,
            };
            mainRecyclerAdapter.SetupRatingViewVisibility(shouldShowRatingViewOnResume);
            touchCallback = new MainRecyclerViewTouchCallback(mainRecyclerAdapter);

            setupRecycler();

            mainRecyclerAdapter.ToggleGroupExpansion
            .Subscribe(ViewModel.TimeEntriesViewModel.ToggleGroupExpansion.Inputs)
            .DisposedBy(DisposeBag);

            mainRecyclerAdapter.TimeEntryTaps
            .Select(editEventInfo)
            .Subscribe(ViewModel.SelectTimeEntry.Inputs)
            .DisposedBy(DisposeBag);

            mainRecyclerAdapter.ContinueTimeEntry
            .Subscribe(ViewModel.ContinueTimeEntry.Inputs)
            .DisposedBy(DisposeBag);

            mainRecyclerAdapter.DeleteTimeEntrySubject
            .Select(vm => vm.RepresentedTimeEntriesIds)
            .Subscribe(ViewModel.TimeEntriesViewModel.DelayDeleteTimeEntries.Inputs)
            .DisposedBy(DisposeBag);

            ViewModel.TimeEntriesViewModel.TimeEntriesPendingDeletion
            .Subscribe(showUndoDeletion)
            .DisposedBy(DisposeBag);

            ViewModel.SyncProgressState
            .Subscribe(updateSyncingIndicator)
            .DisposedBy(DisposeBag);

            refreshLayout.Rx().Refreshed()
            .Subscribe(ViewModel.Refresh.Inputs)
            .DisposedBy(DisposeBag);

            ViewModel.TimeEntries
            .Subscribe(mainRecyclerAdapter.UpdateCollection)
            .DisposedBy(DisposeBag);

            ViewModel.IsTimeEntryRunning
            .Subscribe(updateRecyclerViewPadding)
            .DisposedBy(DisposeBag);

            notificationManager = Activity.GetSystemService(NotificationService) as NotificationManager;
            Activity.BindRunningTimeEntry(notificationManager, ViewModel.CurrentRunningTimeEntry, ViewModel.ShouldShowRunningTimeEntryNotification)
            .DisposedBy(DisposeBag);
            Activity.BindIdleTimer(notificationManager, ViewModel.IsTimeEntryRunning, ViewModel.ShouldShowStoppedTimeEntryNotification)
            .DisposedBy(DisposeBag);

            ViewModel.SwipeActionsEnabled
            .Subscribe(onSwipeActionsChanged)
            .DisposedBy(DisposeBag);

            setupItemTouchHelper(touchCallback);

            ViewModel.TimeEntriesCount
            .Subscribe(timeEntriesCountSubject)
            .DisposedBy(DisposeBag);

            ViewModel.ShouldReloadTimeEntryLog
            .Subscribe(reload)
            .DisposedBy(DisposeBag);

            ViewModel.ShouldShowWelcomeBack
            .Subscribe(onWelcomeBackViewVisibilityChanged)
            .DisposedBy(DisposeBag);

            ViewModel.ShouldShowEmptyState
            .Subscribe(onEmptyStateVisibilityChanged)
            .DisposedBy(DisposeBag);

            ViewModel.ShouldShowRatingView
            .Subscribe(setupRatingViewVisibility)
            .DisposedBy(DisposeBag);

            setupOnboardingSteps();
        }
示例#6
0
        public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            var onCreateStopwatch = localStopwatchProvider.Create(MeasuredOperation.MainActivityOnCreate);
            onCreateStopwatch.Start();

            var view = inflater.Inflate(Resource.Layout.MainFragment, container, false);

            InitializeViews(view);
            setupToolbar();

            runningEntryCardFrame.Visibility = ViewStates.Invisible;

            stopButton.Rx().BindAction(ViewModel.StopTimeEntry, _ => TimeEntryStopOrigin.Manual).DisposedBy(DisposeBag);

            playButton.Rx().BindAction(ViewModel.StartTimeEntry, _ => true).DisposedBy(DisposeBag);
            playButton.Rx().BindAction(ViewModel.StartTimeEntry, _ => false, ButtonEventType.LongPress).DisposedBy(DisposeBag);

            timeEntryCard.Rx().Tap()
                .WithLatestFrom(ViewModel.CurrentRunningTimeEntry,
                    (_, te) => (new[] { te.Id }, EditTimeEntryOrigin.RunningTimeEntryCard))
                .Subscribe(ViewModel.SelectTimeEntry.Inputs)
                .DisposedBy(DisposeBag);

            ViewModel.ElapsedTime
                .Subscribe(timeEntryCardTimerLabel.Rx().TextObserver())
                .DisposedBy(DisposeBag);

            ViewModel.CurrentRunningTimeEntry
                .Select(te => te?.Description ?? "")
                .Subscribe(timeEntryCardDescriptionLabel.Rx().TextObserver())
                .DisposedBy(DisposeBag);

            ViewModel.CurrentRunningTimeEntry
                .Select(te => string.IsNullOrWhiteSpace(te?.Description))
                .Subscribe(timeEntryCardAddDescriptionLabel.Rx().IsVisible())
                .DisposedBy(DisposeBag);

            ViewModel.CurrentRunningTimeEntry
                .Select(te => string.IsNullOrWhiteSpace(te?.Description))
                .Invert()
                .Subscribe(timeEntryCardDescriptionLabel.Rx().IsVisible())
                .DisposedBy(DisposeBag);

            ViewModel.CurrentRunningTimeEntry
                .Select(CreateProjectClientTaskLabel)
                .Subscribe(timeEntryCardProjectClientTaskLabel.Rx().TextFormattedObserver())
                .DisposedBy(DisposeBag);

            var projectVisibilityObservable = ViewModel.CurrentRunningTimeEntry
                .Select(te => te?.Project != null);

            projectVisibilityObservable
                .Subscribe(timeEntryCardProjectClientTaskLabel.Rx().IsVisible())
                .DisposedBy(DisposeBag);

            projectVisibilityObservable
                .Subscribe(timeEntryCardDotContainer.Rx().IsVisible())
                .DisposedBy(DisposeBag);

            var projectColorObservable = ViewModel.CurrentRunningTimeEntry
                .Select(te => te?.Project?.Color ?? "#000000")
                .Select(Color.ParseColor);

            projectColorObservable
                .Subscribe(timeEntryCardDotView.Rx().DrawableColor())
                .DisposedBy(DisposeBag);

            addDrawable = ContextCompat.GetDrawable(Context, Resource.Drawable.add_white);
            playDrawable = ContextCompat.GetDrawable(Context, Resource.Drawable.play_white);

            ViewModel.IsInManualMode
                .Select(isManualMode => isManualMode ? addDrawable : playDrawable)
                .Subscribe(playButton.SetDrawableImageSafe)
                .DisposedBy(DisposeBag);

            ViewModel.IsTimeEntryRunning
                .Subscribe(onTimeEntryCardVisibilityChanged)
                .DisposedBy(DisposeBag);

            ViewModel.SyncProgressState
                .Subscribe(onSyncChanged)
                .DisposedBy(DisposeBag);

            mainRecyclerAdapter = new MainRecyclerAdapter(ViewModel.TimeService)
            {
                SuggestionsViewModel = ViewModel.SuggestionsViewModel,
                RatingViewModel = ViewModel.RatingViewModel,
                StopwatchProvider = localStopwatchProvider
            };
            mainRecyclerAdapter.SetupRatingViewVisibility(shouldShowRatingViewOnResume);

            setupRecycler();

            mainRecyclerAdapter.ToggleGroupExpansion
                .Subscribe(ViewModel.TimeEntriesViewModel.ToggleGroupExpansion.Inputs)
                .DisposedBy(DisposeBag);

            mainRecyclerAdapter.TimeEntryTaps
                .Select(editEventInfo)
                .Subscribe(ViewModel.SelectTimeEntry.Inputs)
                .DisposedBy(DisposeBag);

            mainRecyclerAdapter.ContinueTimeEntry
                .Select(vm => (vm.LogItem.RepresentedTimeEntriesIds.First(), vm.ContinueMode))
                .Subscribe(ViewModel.ContinueTimeEntry.Inputs)
                .DisposedBy(DisposeBag);

            mainRecyclerAdapter.DeleteTimeEntrySubject
                .Select(vm => vm.RepresentedTimeEntriesIds)
                .Subscribe(ViewModel.TimeEntriesViewModel.DelayDeleteTimeEntries.Inputs)
                .DisposedBy(DisposeBag);

            ViewModel.TimeEntriesViewModel.TimeEntriesPendingDeletion
                .Subscribe(showUndoDeletion)
                .DisposedBy(DisposeBag);

            ViewModel.SyncProgressState
                .Subscribe(updateSyncingIndicator)
                .DisposedBy(DisposeBag);

            refreshLayout.Rx().Refreshed()
                 .Subscribe(ViewModel.Refresh.Inputs)
                 .DisposedBy(DisposeBag);

            ViewModel.TimeEntries
                .ObserveOn(SynchronizationContext.Current)
                .Subscribe(mainRecyclerAdapter.UpdateCollection)
                .DisposedBy(DisposeBag);

            ViewModel.IsTimeEntryRunning
                .ObserveOn(SynchronizationContext.Current)
                .Subscribe(updateRecyclerViewPadding)
                .DisposedBy(DisposeBag);

            notificationManager = Activity.GetSystemService(NotificationService) as NotificationManager;
            Activity.BindRunningTimeEntry(notificationManager, ViewModel.CurrentRunningTimeEntry, ViewModel.ShouldShowRunningTimeEntryNotification)
                .DisposedBy(DisposeBag);
            Activity.BindIdleTimer(notificationManager, ViewModel.IsTimeEntryRunning, ViewModel.ShouldShowStoppedTimeEntryNotification)
                .DisposedBy(DisposeBag);
            setupItemTouchHelper(mainRecyclerAdapter);

            ViewModel.TimeEntriesCount
                .Subscribe(timeEntriesCountSubject)
                .DisposedBy(DisposeBag);

            ViewModel.ShouldReloadTimeEntryLog
                .Subscribe(reload)
                .DisposedBy(DisposeBag);

            ViewModel.ShouldShowWelcomeBack
                .Subscribe(onWelcomeBackViewVisibilityChanged)
                .DisposedBy(DisposeBag);

            ViewModel.ShouldShowEmptyState
                .Subscribe(onEmptyStateVisibilityChanged)
                .DisposedBy(DisposeBag);

            ViewModel.ShouldShowRatingView
                .Subscribe(setupRatingViewVisibility)
                .DisposedBy(DisposeBag);

            setupOnboardingSteps();
            onCreateStopwatch.Stop();

            return view;
        }
 public MainRecyclerViewTouchCallback(MainRecyclerAdapter adapter) : base(0, ItemTouchHelper.Left | ItemTouchHelper.Right)
 {
     this.adapter = adapter;
 }
 public void Update(GeoLocation loc)
 {
     GeoLocation = loc;
     adapter     = new MainRecyclerAdapter(ExhibitSet, GeoLocation, Application.Context);
     recyclerView.SetAdapter(adapter);
 }
示例#9
0
        protected override void OnCreate(Bundle bundle)
        {
            var setup = MvxAndroidSetupSingleton.EnsureSingletonAvailable(ApplicationContext);

            setup.EnsureInitialized();

            base.OnCreate(bundle);
            var onCreateStopwatch = localStopwatchProvider.Create(MeasuredOperation.MainActivityOnCreate);

            onCreateStopwatch.Start();
            SetContentView(Resource.Layout.MainActivity);
            OverridePendingTransition(Resource.Animation.abc_fade_in, Resource.Animation.abc_fade_out);

            InitializeViews();

            SetSupportActionBar(FindViewById <Toolbar>(Resource.Id.Toolbar));
            SupportActionBar.SetDisplayShowHomeEnabled(false);
            SupportActionBar.SetDisplayShowTitleEnabled(false);

            runningEntryCardFrame.Visibility = ViewStates.Invisible;

            reportsView.Rx().BindAction(ViewModel.OpenReports).DisposedBy(DisposeBag);
            settingsView.Rx().BindAction(ViewModel.OpenSettings).DisposedBy(DisposeBag);
            stopButton.Rx().BindAction(ViewModel.StopTimeEntry, _ => TimeEntryStopOrigin.Manual).DisposedBy(DisposeBag);

            playButton.Rx().BindAction(ViewModel.StartTimeEntry, _ => true).DisposedBy(DisposeBag);
            playButton.Rx().BindAction(ViewModel.StartTimeEntry, _ => false, ButtonEventType.LongPress).DisposedBy(DisposeBag);

            timeEntryCard.Rx().Tap()
            .WithLatestFrom(ViewModel.CurrentRunningTimeEntry, (_, te) => te.Id)
            .Subscribe(ViewModel.SelectTimeEntry.Inputs)
            .DisposedBy(DisposeBag);

            ViewModel.ElapsedTime
            .Subscribe(timeEntryCardTimerLabel.Rx().TextObserver())
            .DisposedBy(DisposeBag);

            ViewModel.CurrentRunningTimeEntry
            .Select(te => te?.Description ?? "")
            .Subscribe(timeEntryCardDescriptionLabel.Rx().TextObserver())
            .DisposedBy(DisposeBag);

            ViewModel.CurrentRunningTimeEntry
            .Select(te => string.IsNullOrWhiteSpace(te?.Description))
            .Subscribe(timeEntryCardAddDescriptionLabel.Rx().IsVisible())
            .DisposedBy(DisposeBag);

            ViewModel.CurrentRunningTimeEntry
            .Select(te => string.IsNullOrWhiteSpace(te?.Description))
            .Invert()
            .Subscribe(timeEntryCardDescriptionLabel.Rx().IsVisible())
            .DisposedBy(DisposeBag);

            ViewModel.CurrentRunningTimeEntry
            .Select(createProjectClientTaskLabel)
            .Subscribe(timeEntryCardProjectClientTaskLabel.Rx().TextFormattedObserver())
            .DisposedBy(DisposeBag);

            var projectVisibilityObservable = ViewModel.CurrentRunningTimeEntry
                                              .Select(te => te?.Project != null);

            projectVisibilityObservable
            .Subscribe(timeEntryCardProjectClientTaskLabel.Rx().IsVisible())
            .DisposedBy(DisposeBag);

            projectVisibilityObservable
            .Subscribe(timeEntryCardDotContainer.Rx().IsVisible())
            .DisposedBy(DisposeBag);

            var projectColorObservable = ViewModel.CurrentRunningTimeEntry
                                         .Select(te => te?.Project?.Color ?? "#000000")
                                         .Select(Color.ParseColor);

            projectColorObservable
            .Subscribe(timeEntryCardDotView.Rx().DrawableColor())
            .DisposedBy(DisposeBag);

            var addDrawable  = ContextCompat.GetDrawable(this, Resource.Drawable.add_white);
            var playDrawable = ContextCompat.GetDrawable(this, Resource.Drawable.play_white);

            ViewModel.IsInManualMode
            .Select(isInManualMode => isInManualMode ? addDrawable : playDrawable)
            .Subscribe(playButton.SetImageDrawable)
            .DisposedBy(DisposeBag);

            ViewModel.IsTimeEntryRunning
            .Subscribe(onTimeEntryCardVisibilityChanged)
            .DisposedBy(DisposeBag);

            ViewModel.SyncProgressState
            .Subscribe(onSyncChanged)
            .DisposedBy(DisposeBag);

            mainRecyclerAdapter = new MainRecyclerAdapter(ViewModel.TimeEntries, ViewModel.TimeService)
            {
                SuggestionsViewModel = ViewModel.SuggestionsViewModel,
                RatingViewModel      = ViewModel.RatingViewModel,
                StopwatchProvider    = localStopwatchProvider
            };

            mainRecyclerAdapter.TimeEntryTaps
            .Select(te => te.Id)
            .Subscribe(ViewModel.SelectTimeEntry.Inputs)
            .DisposedBy(DisposeBag);

            mainRecyclerAdapter.ContinueTimeEntrySubject
            .Subscribe(ViewModel.ContinueTimeEntry.Inputs)
            .DisposedBy(DisposeBag);

            mainRecyclerAdapter.DeleteTimeEntrySubject
            .Subscribe(ViewModel.TimeEntriesViewModel.DelayDeleteTimeEntry.Inputs)
            .DisposedBy(DisposeBag);

            ViewModel.TimeEntriesViewModel.ShouldShowUndo
            .Subscribe(showUndoDeletion)
            .DisposedBy(DisposeBag);

            ViewModel.SyncProgressState
            .Subscribe(updateSyncingIndicator)
            .DisposedBy(DisposeBag);

            refreshLayout.Rx().Refreshed()
            .Subscribe(ViewModel.Refresh.Inputs)
            .DisposedBy(DisposeBag);

            setupLayoutManager(mainRecyclerAdapter);

            ViewModel.TimeEntries.CollectionChange
            .ObserveOn(SynchronizationContext.Current)
            .Subscribe(mainRecyclerAdapter.UpdateCollection)
            .DisposedBy(DisposeBag);

            ViewModel.IsTimeEntryRunning
            .ObserveOn(SynchronizationContext.Current)
            .Subscribe(updateRecyclerViewPadding)
            .DisposedBy(DisposeBag);

            notificationManager = GetSystemService(NotificationService) as NotificationManager;
            this.BindRunningTimeEntry(notificationManager, ViewModel.CurrentRunningTimeEntry, ViewModel.ShouldShowRunningTimeEntryNotification)
            .DisposedBy(DisposeBag);
            this.BindIdleTimer(notificationManager, ViewModel.IsTimeEntryRunning, ViewModel.ShouldShowStoppedTimeEntryNotification)
            .DisposedBy(DisposeBag);
            setupItemTouchHelper(mainRecyclerAdapter);

            ViewModel.TimeEntriesCount
            .Subscribe(timeEntriesCountSubject)
            .DisposedBy(DisposeBag);

            ViewModel.ShouldReloadTimeEntryLog
            .Subscribe(reload)
            .DisposedBy(DisposeBag);

            ViewModel.ShouldShowWelcomeBack
            .Subscribe(onWelcomeBackViewVisibilityChanged)
            .DisposedBy(DisposeBag);

            ViewModel.ShouldShowEmptyState
            .Subscribe(onEmptyStateVisibilityChanged)
            .DisposedBy(DisposeBag);

            setupOnboardingSteps();
            onCreateStopwatch.Stop();
        }