Skip to content

[MBL-19703][Student] Add Progress Notifications Widget to Dashboard#3508

Merged
hermannakos merged 4 commits intomasterfrom
MBL-19703-progress-notification-widget
Feb 13, 2026
Merged

[MBL-19703][Student] Add Progress Notifications Widget to Dashboard#3508
hermannakos merged 4 commits intomasterfrom
MBL-19703-progress-notification-widget

Conversation

@hermannakos
Copy link
Copy Markdown
Collaborator

@hermannakos hermannakos commented Feb 5, 2026

Test plan:

  1. Upload a file to an assignment submission
    • Verify the progress widget appears on the dashboard
    • Verify progress bar updates during upload
    • Tap the completed upload to navigate to submission details
    • Dismiss a completed/failed upload
  2. Upload a file to My Files
    • Verify progress widget appears
    • Tap completed upload to navigate to the folder
  3. Trigger offline sync (if available)
    • Verify sync progress card appears with dark background
    • Verify progress updates during sync
    • Tap to open sync progress screen
    • On error, verify dismiss button appears
  4. Test with multiple concurrent uploads
    • Verify pager navigation between cards

refs: MBL-19703
affects: Student
release note: Students can now see file upload and offline sync progress directly on the Dashboard

  • Follow-up e2e test ticket created or not needed
  • Tested in dark mode
  • Tested in light mode
  • Test in landscape mode and/or tablet
  • A11y checked
  • Approve from product

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.

Progress Widget Implementation Review

Great work on implementing the Progress Widget! This is a well-architected feature with excellent test coverage and proper use of modern Android development patterns. Here's my comprehensive review:

✅ Strengths

  • Clean Architecture: Excellent separation of concerns with dedicated use cases, proper MVVM pattern, and router abstraction
  • Outstanding Test Coverage: 38 test cases across 5 test files covering use cases and ViewModel thoroughly
  • Modern Tech Stack: Proper use of Jetpack Compose, Kotlin Flow, Room with Flow-based queries, and Dagger Hilt
  • Reactive Design: Real-time updates using Flow for both upload progress and sync status
  • Good UX: Visual feedback with colored backgrounds, pagination for multiple items, and smart navigation

📋 Issues Found

I've added inline comments for the following items that should be addressed:

  • ObserveUploadsUseCase.kt:47 - Add error logging for invalid UUID parsing (currently fails silently)
  • DismissUploadUseCase.kt:35 - Add logging when entity is not found during dismiss
  • ProgressViewModel.kt:138 - Remove unused refresh() method or add TODO explaining future intention
  • ProgressWidget.kt:132 - Memoize pager state to prevent scroll position resets on recomposition
  • ObserveUploadsUseCase.kt:56 - Consider performance testing with 10+ simultaneous uploads (Flow combination overhead)
  • ProgressWidget.kt:269 - Consider adding dismiss button to upload error cards for UX consistency with sync errors

🧪 Test Coverage Gap

While use case and ViewModel tests are excellent, consider adding Compose UI tests in androidTest to verify:

  • Widget rendering with different states
  • User interactions (clicks, dismissals)
  • Pagination behavior
  • Accessibility

💡 Additional Observations

  • Widget Positioning: The progress widget is now positioned first in the default widget list. Ensure this aligns with UX expectations.
  • Performance: The current Flow combination approach works well for typical usage, but should be monitored with many concurrent uploads.

Overall Assessment

This is a solid, production-ready implementation with only minor improvements needed. The architecture is clean, tests are comprehensive, and the code follows best practices. Once the logging improvements are added and the pager state is memoized, this will be excellent to merge.

Nice work! 🎉


private fun clearSnackbar() {
_uiState.update { it.copy(snackbarMessage = null) }
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This refresh() method is a no-op. If reactive observation is the intended design (which makes sense for this widget), consider removing this callback entirely to avoid confusion. If you anticipate needing manual refresh in the future, add a TODO comment explaining the intention.

.padding(horizontal = 16.dp)
.padding(bottom = 12.dp),
text = stringResource(R.string.progressWidgetTitle),
fontSize = 14.sp,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The pager state should be memoized to prevent potential scroll position resets on recomposition. Consider using a key parameter:

val pagerState = rememberPagerState(
    pageCount = { itemPages.size },
    key = itemPages.size  // Prevents reset when size doesn't change
)

Or better yet, track the current page index in the ViewModel if the pages can change dynamically.

if (item.state != UploadState.UPLOADING) {
IconButton(
onClick = onDismiss,
modifier = Modifier
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

For consistency with the sync error card (which has a dismiss button), consider adding a dismiss option for failed uploads. This would give users a consistent way to clear error states from the widget.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Feb 5, 2026

🧪 Unit Test Results

✅ 📱 Student App

  • Tests: 1240 total, 0 failed, 0 skipped
  • Duration: 0.000s
  • Success Rate: 100%

✅ 🌅 Horizon

  • Tests: 623 total, 0 failed, 0 skipped
  • Duration: 37.043s
  • Success Rate: 100%

✅ 📦 Submodules

  • Tests: 3022 total, 0 failed, 0 skipped
  • Duration: 60.620s
  • Success Rate: 100%

📊 Summary

  • Total Tests: 4885
  • Failed: 0
  • Skipped: 0
  • Status: ✅ All tests passed!

Last updated: Fri, 13 Feb 2026 10:40:54 GMT

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Feb 5, 2026

Student Install Page

@tamaskozmer tamaskozmer self-requested a review February 5, 2026 13:41
Migrate progress notification functionality from DashboardNotificationsFragment
to the new widget system. The widget displays file upload progress and offline
sync progress with reactive updates.

New components:
- ProgressWidget: Compose UI with HorizontalPager for progress cards
- ProgressViewModel: Observes uploads and sync progress reactively
- Use cases: ObserveUploads, ObserveSync, DismissUpload, DismissSync
- StudentProgressWidgetRouter: Navigation for uploads and sync screens

Features:
- Upload progress cards with colored icon strip and progress bar
- Sync progress cards with dark background (licorice/danger)
- Click to navigate to submission details or file folder
- Dismiss completed/failed uploads and sync errors
- Database transactions for safe cleanup operations

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@hermannakos hermannakos force-pushed the MBL-19703-progress-notification-widget branch from 73f1f69 to 28cf697 Compare February 5, 2026 14:04
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Feb 5, 2026

📊 Code Coverage Report

⚠️ Student

  • PR Coverage: 43.11%
  • Master Coverage: 43.16%
  • Delta: -0.04%

✅ Teacher

  • PR Coverage: 25.39%
  • Master Coverage: 25.39%
  • Delta: +0.00%

⚠️ Pandautils

  • PR Coverage: 23.19%
  • Master Coverage: 23.20%
  • Delta: -0.00%

📈 Overall Average

  • PR Coverage: 30.57%
  • Master Coverage: 30.58%
  • Delta: -0.02%

Copy link
Copy Markdown
Contributor

@kdeakinstructure kdeakinstructure left a comment

Choose a reason for hiding this comment

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

  • There is no Dashboard notification when uploading a file assignment submission
  • Also, in landscape mode, the notifications (and also the course invitations and welcome widget) is not "responsible", they should fill the width of the landscape screen just like the other widgets (e.g. Courses, Groups, Forecast).
Screen_recording_20260208_154509.mp4

hermannakos and others added 2 commits February 12, 2026 14:01
- Updated Progress Widget design based on Figma:
  - Upload notifications: dark card (in-progress), green card (success), red card (error)
  - Sync notifications: dark card (in-progress/queued), red card (error)
  - Changed from HorizontalPager to grid layout
  - Removed "Progress" title from widget
- Resolved merge conflicts with master:
  - Added PROGRESS and CONFERENCES/TODO widget constants
  - Updated widget positions (PROGRESS at 0, CONFERENCES at 1)
  - Added all new widget router bindings

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@kdeakinstructure kdeakinstructure left a comment

Choose a reason for hiding this comment

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

QA 👍

@hermannakos hermannakos merged commit 8060409 into master Feb 13, 2026
28 checks passed
@hermannakos hermannakos deleted the MBL-19703-progress-notification-widget branch February 13, 2026 15:01
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.

3 participants