Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New way of habit status computation #6

Merged
merged 22 commits into from
Jan 11, 2024
Merged

New way of habit status computation #6

merged 22 commits into from
Jan 11, 2024

Conversation

DanielRendox
Copy link
Owner

@DanielRendox DanielRendox commented Jan 7, 2024

The idea of this PR

Currently, the app computes habit statuses and saves them to the database whenever GetRoutineStatusUseCase.invoke is called. While this makes it easier to figure out when the habit has some backlog or is completed ahead, this architecture has a huge pitfall. The saved data becomes outdated whenever the habit is completed or uncompleted. It's quite tricky to update every past calendar date every time it happens. Such a way of doing things may result in various bugs, unexpected behavior, and unclear code.
This PR provides a robust solution to this problem, while keeping the intended behavior. From now on, the database doesn't cash anything and keeps only necessary data such as the date mapped to how many times the habit was completed. The statuses are computed on the go. This functionality is located in the HabitComputeStatusUseCase and thoroughly tested in HabitComputeStatusUseCaseTest class.

How the main problem is solved

The problematic cases such as backlog and completing ahead are solved by computing the schedule deviation. computeScheduleDeviation function considers how many times the habit is due during the specified period and how many times it's completed during that period.

What changes are made

Implement pagination for routine calendar

Since the data is no longer cashed, it takes some time for it to be computed and shown on the screen. To maintain the native look and feel of the app, custom pagination was introduced for the calendar so that the data loading process seems to be instantaneous to the user. By pagination, I mean just loading habit statuses for future and past months even though they are not yet visible on the screen, not an official paging implementation.

Without pagination (left) and with pagination (right)

RoutineTracker_PR_6_changes_demonstration_pagination.mp4

Additional changes

  • Adapted the rest of the project to meet the new way of habit status computation.
  • Refactored Routine to Habit across the project because the term "routine" should represent an activity that is done in a fixed period of time. That could also be repeating tasks, events, and other things. So while the routine is still kept in many places where it implies such an abstract term, from now on things are called by their proper names.
  • Fixed various minor bugs and performance issues.

Daniel and others added 14 commits December 20, 2023 10:42
refactor routine to habit;
use HabitStatus instead of HistoricalStatus and PlanningStatus;
add additional statuses for clarity;
rewrite logic of habit status computation so that both: historical and future statuses can be computed on the go instead of being cashed in the database, the only data that needs to be stored is number of times completed;
Add the corresponding fakes and refactor some existing data sources
Refactor Routine to Habit along the way.

The app currently works well, but the habit streak functionality is not working. It always displays zeros in the current/latest streak cards. Streak functionality is also required to determine the color of an ambiguous date in RoutineCalendar, such as one that is associated with NotDue or Skipped habit status. So these days are displayed with the green (completed) color at the moment.

The is also a lot of minor improvements and fixes to be done including refactoring Routine to Habit in the scope of the whole project
The detailed list of changes will be written upon the MVP release along with documenting the project, providing it's description in README.md, etc.
Increase the speed of habit statuses computation on RoutineCalendarScreen by computing each date in a separate coroutine
Introduce pagination for RoutineCalendarScreen so that the status computation process is not visible to the user
Improve RoutineCalendarViewModel's code
Configure pagination for RoutineCalendar
Move habit status computation off the main thread but only in RoutineCalendarViewModel (bad practice, should be fixed soon)
Keep Routine in all places where it represents an abstract term and may imply a simple task, for example.
@DanielRendox DanielRendox added enhancement New feature or request bug_fix labels Jan 7, 2024
@DanielRendox
Copy link
Owner Author

@CodiumAI-Agent /update_changelog

@CodiumAI-Agent
Copy link

Changelog updates:

2024-01-07

Changed

  • Updated the core functionality of the app to compute habit statuses on the go instead of caching them in the database. This change improves the robustness and clarity of the code.
  • Refactored 'Routine' to 'Habit' across the application for better semantics.
  • Improved performance by computing each date in a separate coroutine and introduced pagination for the RoutineCalendarScreen.
  • Updated the UI to support the insert/delete habit completion functionality.

Fixed

  • Fixed various minor bugs and performance issues.

to commit the new content to the CHANGELOG.md file, please type:
'/update_changelog --pr_update_changelog.push_changelog_changes=true'

To document the changes in the #6 PR
- Don't fetch data from repository in for loops in HabitComputeStatusUseCase. Instead, get lists of data only once and then operate on them.
- Add new functionality to vacation data sources.
- Optimize coroutines in RoutineCalendarViewModel.
 They now get cancelled when the data gets outdated. This way, we don't waste resources because the same month's data is not loaded simultaneously.
Calendar dates have been loading rather slowly after a completion, especially when multiple dates were clicked at the same time. To sort out this issue, I changed the code to reload only the current month and delete all the others. Although with this approach, a visible delay in data load gets appeared upon scroll to another month, this issue is minuscule compared to the previous ones.
- Switch to Dispatchers.Default in HabitComputeStatusUseCase instead of doing that in RoutineCalendarViewModel
- Minor fix - classify already completed status to two status for future and past dates. That's necessary because the RoutineCalendar will display wrong colors for future dates otherwise
- Don't provide Dispatchers.IO with Koin because it provides this dispatcher for all coroutine contexts, which is an undesired behaviour. Make it a default value for all existing local data sources instead.
@DanielRendox DanielRendox changed the title Update the core functionality New way of habit status computation Jan 11, 2024
Repository owner deleted a comment from CodiumAI-Agent Jan 11, 2024
Repository owner deleted a comment from CodiumAI-Agent Jan 11, 2024
Repository owner deleted a comment from CodiumAI-Agent Jan 11, 2024
Repository owner deleted a comment from CodiumAI-Agent Jan 11, 2024
Repository owner deleted a comment from CodiumAI-Agent Jan 11, 2024
Repository owner deleted a comment from CodiumAI-Agent Jan 11, 2024
Repository owner deleted a comment from CodiumAI-Agent Jan 11, 2024
Repository owner deleted a comment from CodiumAI-Agent Jan 11, 2024
@DanielRendox DanielRendox merged commit c94ab59 into main Jan 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug_fix enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants