Skip to content

[MBL-19695][S/T/P] Fix issue of non-updating calendars filter screen when calendar options changes#3892

Closed
suhaibabsi-inst wants to merge 5 commits into
masterfrom
bugfix/MBL-19695-NonUpdaing-Calendars-Filter-Screen
Closed

[MBL-19695][S/T/P] Fix issue of non-updating calendars filter screen when calendar options changes#3892
suhaibabsi-inst wants to merge 5 commits into
masterfrom
bugfix/MBL-19695-NonUpdaing-Calendars-Filter-Screen

Conversation

@suhaibabsi-inst
Copy link
Copy Markdown
Contributor

@suhaibabsi-inst suhaibabsi-inst commented Feb 18, 2026

refs: MBL-19695
affects: Student, Teacher, Parent
builds: Student, Teacher, Parent
release note: Fixed issue of non-updating calendars filter screen when calendar options changes

Fixes an issue where the calendar filter screen's selection lists weren't reflecting updates to the filter options. Added .id() modifiers to force view recreation when the underlying calendar options change, ensuring the UI stays in sync with the data.

Changes:

  • Implemented hash-based ID generation based on filter options to detect visual changes.
  • Assigned hash-based ID as view identifiers to user, course, and group filter multi-selection view.

Test Plan

Prerequisites

Navigate to Calendar → Filter screen

Test Cases

1. Course list updates

  • Open calendar filter screen
  • Enroll/unenroll from a course (via web)
  • Pull to refresh calendar
  • Reopen filter screen
  • ✓ Course list reflects changes

2. Group list updates

  • Open calendar filter screen
  • Join/leave a group (via web)
  • Pull to refresh calendar
  • Reopen filter screen
  • ✓ Group list reflects changes

3. Selection state persists

  • Select several filters
  • Trigger a filter list update (add/remove course)
  • ✓ Previously selected filters remain selected
  • ✓ New items appear correctly

4. Metadata updates

  • Change a course name or color (via web)
  • Refresh and reopen filter screen
  • ✓ Updated names and colors display correctly

Checklist

  • Follow-up e2e test ticket created
  • A11y checked
  • Tested on phone
  • Tested on tablet
  • Tested in dark mode
  • Tested in light mode
  • Approve from product

…ions changes

refs: MBL-19695
affects: Student, Teacher, Parent
builds: Student, Teacher, Parent
release note: Fixed issue of non-updating calendars filter screen when calendar options changes
@suhaibabsi-inst suhaibabsi-inst self-assigned this Feb 18, 2026
Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

This PR addresses a SwiftUI view update issue by adding stable identifiers to MultiSelectionView components using a custom hashing mechanism. The approach is reasonable, but there are some concerns about the hash implementation.

Issues Found

  • Hash inconsistency with OptionItem conformance - The custom hashValueForViewID includes properties (title, subtitle, color, headerTitle) that aren't part of OptionItem's Equatable/Hashable implementation, which only uses id. This could lead to unexpected behavior (CalendarFilterScreen.swift:129-138)
  • Non-deterministic hash values - Hasher.finalize() doesn't guarantee stable hash values across app launches, which could cause issues if view identity needs to persist (CalendarFilterScreen.swift:129-130)

Positive Feedback

  • Good use of the .id() modifier to force SwiftUI view updates when the underlying data changes
  • The extension is properly scoped as private to avoid namespace pollution
  • Clear documentation explaining the purpose of the workaround
  • Follows Swift naming conventions and code style

Suggestions

Consider whether you need to detect changes in properties beyond id. If id changes are sufficient to trigger updates, simplify the hash to only use id. If you need to detect other property changes, consider using a more explicit approach like concatenating property values into a deterministic string or using a structure that better represents your intent.

Overall, the solution addresses the immediate problem but could benefit from refinement in the hashing logic to avoid potential edge cases.

Comment thread Core/Core/Features/Planner/CalendarFilter/View/CalendarFilterScreen.swift Outdated
Comment thread Core/Core/Features/Planner/CalendarFilter/View/CalendarFilterScreen.swift Outdated
@inst-danger
Copy link
Copy Markdown
Contributor

inst-danger commented Feb 18, 2026

Release Note:

Fixed issue of non-updating calendars filter screen when calendar options changes

Affected Apps: Student, Teacher, Parent

Builds: Student, Teacher, Parent

MBL-19695

Coverage New % Master % Delta
Canvas iOS 91.88% 81.06% 10.82%

Generated by 🚫 dangerJS against 56a72f0

@inst-danger
Copy link
Copy Markdown
Contributor

inst-danger commented Feb 18, 2026

Builds

Commit: Merge branch 'master' into bugfix/MBL-19695-NonUpdaing-Calendars-Filter-Screen (960fe03)
Build Number: 1486
Built At: Mar 05 19:32 CET (03/05 11:32 AM MST)

Student
Teacher
Parent

@suhaibabsi-inst suhaibabsi-inst marked this pull request as ready for review February 18, 2026 12:47
Copy link
Copy Markdown
Collaborator

@vargaat vargaat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This solution seems like a code smell for me, maybe with MultiSelectionView itself that would be nice to have fixed, to fix all such issues in the future. With the id of the selectionview being generated by all of its items will result in re-creating the whole view instead of just updating the one cell that actually changed. This might not be a problem here and fixes the issue but I feel something fundamental is broken here.

Could you check again the update logic of this?

@suhaibabsi-inst
Copy link
Copy Markdown
Contributor Author

suhaibabsi-inst commented Feb 22, 2026

This solution seems like a code smell for me, maybe with MultiSelectionView itself that would be nice to have fixed, to fix all such issues in the future. With the id of the selectionview being generated by all of its items will result in re-creating the whole view instead of just updating the one cell that actually changed. This might not be a problem here and fixes the issue but I feel something fundamental is broken here.

Could you check again the update logic of this?

Yes, that was like a kind of hacky solution.

.. I feel something fundamental is broken here.

That's correct. Upon digging deep into MultiSelectionView, seems like what caused the issue is the use StateObject attribute for view model. By investigating more into the inner properties of it, turned out we shouldn't be using that for the following reasons:

  • Properties used for view configuration like (allOptions, title) are set to the view model as constant, @Published was not used for them. Which means that setting a new view model with those changed, makes it necessary for the view to redraw to show updates on them. Thus it requires the use of ObservedObject for attribute.

  • Selection is managed by a CurrentValueSubject instance, property selectedOptions, and there are already subscriptions installed in view model to follow updates on it, and to direct the view to redraw (by calling objectWillChange.send()). StateObject vs ObservedObject doesn't make any difference here.

Fixed the code to have like it that.

self.hasAllSelectionButton = hasAllSelectionButton

self._viewModel = StateObject(wrappedValue: .init(
self.viewModel = .init(
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this works because the Observed object is re-created on each render and that re-initializes it with the updated allOptions array, right?

As I see, the core issue with the view and the view model is that it was simply not created for changing allOptions or title properties. In the original implementation the MultiSelectionViewModel was a @StateObject that was only created once on the first view init with a set of title and allOptionsproperties. Even if these properties did change in some upper level, theMultiSelectionViewModel` was never re-created, thus the changes never reflected on the UI.

  • One fix would be to keep MultiSelectionViewModel as an ObservedObject and store it in the hosting view, make its title and allOptions @Published.
  • Another idea is to keep the @StateObject but move title and allObjects as view properties of MultiSelectionView. Maybe this is simpler than the above as it requires less refactoring.

@rh12 What do you think?

Copy link
Copy Markdown
Contributor Author

@suhaibabsi-inst suhaibabsi-inst Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly, what made my choice to use the ID synthesizing technique I used before is to avoid missing around with StateObject, as it can get us into few problems. But I forgot about that getting busy with other bugs out of urgency. So, I am favor now of getting back to my previous solution 🙃.

Problems with 2 suggestions above:
1- Using @ObservedObject will force view creation on each body calling of the container view. Even when putting title and allOptions as @Published. Which might not be efficient in a lot of cases.

Upon speaking with Attila about it, I think this point is not valid. The new understanding is we can have some way to move the viewModel of MultiSelectionView to the original viewModel of container view, then have it passed to MultiSelectionView as an ObservedObject. This way the mere updating of @Published allOptions property will do the job without the effect of view re-rendering on each view initialization.

2- The second is a good alternative, but still we need to pass allOptions to the viewModel as it is needed there. it can feel redundant to do so, but at least it is more efficient than having to turn it to @ObservedObject

I would leave the last call for @rh12 on that, of course.

@petkybenedek petkybenedek deleted the bugfix/MBL-19695-NonUpdaing-Calendars-Filter-Screen branch February 23, 2026 14:45
@petkybenedek petkybenedek restored the bugfix/MBL-19695-NonUpdaing-Calendars-Filter-Screen branch February 23, 2026 14:48
@petkybenedek petkybenedek reopened this Feb 23, 2026
@bitrise
Copy link
Copy Markdown
Contributor

bitrise Bot commented Mar 5, 2026

Release Note:

Fixed issue of non-updating calendars filter screen when calendar options changes

Affected Apps: Student, Teacher, Parent

Builds: Student, Teacher, Parent

MBL-19695

Coverage New % Master % Delta
Canvas iOS 91.86% 81.06% 10.8%

Generated by 🚫 dangerJS against 960fe03

@suhaibabsi-inst suhaibabsi-inst marked this pull request as draft March 23, 2026 13:32
@suhaibabsi-inst
Copy link
Copy Markdown
Contributor Author

To be revisited later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants