Skip to content

Conversation

@domonkosadam
Copy link
Contributor

refs:
affects: Student
release note: Career - Redesigned Learn screen

domonkosadam and others added 5 commits January 27, 2026 10:40
refs: CLX-3742
affects: Student
release note: none
refs: CLX-3743
affects: Student
release note: none
refs: CLXR-57
affects: Student
release note: none

---------

Co-authored-by: Claude Sonnet 4.5 <[email protected]>
@github-actions
Copy link

github-actions bot commented Feb 9, 2026

🧪 Unit Test Results


📊 Summary

  • Total Tests: 0
  • Failed: 0
  • Skipped: 0
  • Status: ⚠️ No test results found

Last updated: Mon, 09 Feb 2026 09:39:51 GMT

Copy link

@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.

PR Review Summary

This PR implements a major refactoring of the Horizon module's "Learn" feature, reorganizing the navigation architecture and file structure. I've analyzed all 121 changed files (5,743 additions, 3,141 deletions).

Overview of Changes

  • Navigation simplification: Consolidates from dual navigation controllers (main + home) to a single unified controller
  • File reorganization: Restructures course/program features into details/ and list/ subdirectories
  • New API capability: Adds GraphQL query for fetching individual courses (getCourseWithProgressById())
  • Data model enhancement: Adds courseImageUrl field to CourseWithProgress
  • Learn tab refactoring: Implements tabbed navigation (Courses vs Programs)
  • Comprehensive test updates: 40+ test files modified to reflect new architecture

Issues Found

  • Critical: Null handling in HorizonGetCoursesManager.kt:61-71 - Returns success with invalid data (-1L, empty strings) when course not found. Should return DataResult.Fail() instead.
  • Medium: App restart behavior in DashboardViewModel.kt:106 - localeUtils.restartApp() immediately restarts the app, which could be disruptive. Consider deferring or adding user confirmation.
  • Low: Route handling in InterwebsToApplication.kt:214-221 - Ensure thorough testing of Horizon routing with career view flag enabled/disabled.
  • Style: Missing newline at EOF in HorizonGetCourseById.graphql:19

Positive Aspects

Architecture improvements:

  • The navigation simplification significantly reduces complexity and potential for navigation bugs
  • Better file organization follows clean architecture principles and improves code discoverability
  • Type-safe navigation with sealed classes and proper route definitions

Code quality:

  • Comprehensive test coverage with 40+ test files updated
  • Removal of force unwrap operator (!!) in favor of safer alternatives
  • Consistent patterns across new repository and ViewModel classes (Hilt injection, StateFlow)
  • New GraphQL API enables more efficient single-course fetching

Developer experience:

  • Clear separation of concerns with distinct components for course list and program list
  • Feature modularization following single responsibility principle
  • Good error handling patterns (with room for improvement noted above)

Recommendations

  1. Address the critical null handling issue in getCourseWithProgressById() before merging
  2. Review the app restart behavior and consider UX improvements
  3. Given the scope of changes (121 files), ensure thorough integration and manual testing, especially for navigation flows
  4. For future similar refactorings, consider breaking into smaller PRs (e.g., navigation changes separate from file reorganization)

Overall, this is a well-structured refactoring that modernizes the Horizon Learn feature. The navigation simplification is a positive change that should improve long-term maintainability.

return DataResult.Success(course)
} catch (e: Exception) {
DataResult.Fail(Failure.Exception(e))
}
Copy link

Choose a reason for hiding this comment

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

Potential bug: Returning success with invalid data when course not found

The current implementation uses -1L as a fallback for courseId and empty strings for other fields, then returns DataResult.Success even when the course doesn't exist. This could lead to confusing behavior for callers.

Consider checking if the course data is valid and returning a failure result when not found:

val course = result.legacyNode?.onCourse
if (course?.id == null) {
    return DataResult.Fail()
}

val courseId = course.id.toLongOrNull() ?: return DataResult.Fail()
val courseName = course.name ?: ""
val courseImageUrl = course.courseImage?.url ?: ""

CourseWithProgress(
    courseId = courseId,
    courseName = courseName,
    courseCode = course.courseCode ?: "",
    courseImageUrl = courseImageUrl,
    courseProgress = result.progress?.let {
        CourseProgress(
            requirementCount = it.requirementCount ?: 0,
            requirementCompletedCount = it.requirementCompletedCount ?: 0,
            nextRequirementUrl = it.nextRequirement?.htmlUrl ?: "",
            completedAt = it.completedAt
        )
    }
)

}
}
}
} No newline at end of file
Copy link

Choose a reason for hiding this comment

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

Style: Missing newline at end of file

This file should end with a newline character per standard conventions.

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent)
} else {
RouteMatcher.routeUrl(this@InterwebsToApplication, url, domain)
Copy link

Choose a reason for hiding this comment

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

Question: Route handling for Horizon feature

This adds routing logic to direct users to HorizonActivity when the career view flag is enabled.

Please ensure:

  1. This behavior is thoroughly tested with the flag both enabled and disabled
  2. The route params (ROUTE_HORIZON_CAREER_COURSE_ID, etc.) are properly validated
  3. Consider what happens if ApiPrefs.canvasCareerView changes state while the app is running

if (apiPrefs.effectiveLocale != oldLocale) {
localeUtils.restartApp(context)
}
}
Copy link

Choose a reason for hiding this comment

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

Potential UX concern: App restart behavior

The localeUtils.restartApp(context) call will immediately restart the entire app when the user's locale is saved. This could be disruptive if the user is in the middle of a task.

Consider:

  1. Is an immediate restart necessary, or could this be deferred until next app launch?
  2. Should there be user confirmation before restarting?
  3. Ensure this behavior is documented and expected

@github-actions
Copy link

github-actions bot commented Feb 9, 2026

📊 Code Coverage Report

⚠️ Student

  • PR Coverage: 43.25%
  • Master Coverage: 43.27%
  • Delta: -0.02%

✅ Teacher

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

✅ Pandautils

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

📈 Overall Average

  • PR Coverage: 30.54%
  • Master Coverage: 30.55%
  • Delta: -0.01%

@domonkosadam domonkosadam merged commit 0f72de0 into master Feb 9, 2026
76 of 98 checks passed
@domonkosadam domonkosadam deleted the feature/learn-screen-redesign branch February 9, 2026 13:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants