-
Notifications
You must be signed in to change notification settings - Fork 0
refactor(course): Isolate lesson content types through router orchestration #53
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
Open
syed-tp
wants to merge
2
commits into
ref/dio-singleton
Choose a base branch
from
ref/lesson-detail
base: ref/dio-singleton
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| schema: spec-driven | ||
| created: 2026-03-31 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| ## Context | ||
|
|
||
| Currently, the lesson detail implementation is split between multiple screens, each with its own boilerplate for data management. We want to move to a "Domain Partitioning" model where the Router decides which specialized screen to show, instead of relying on a "Shell" widget that delegates internally. | ||
|
|
||
| ## Goals / Non-Goals | ||
|
|
||
| **Goals:** | ||
|
|
||
| - **Isolate PDF content**: Move PDF-specific logic to `PdfLessonDetailScreen`. | ||
| - **Router-First Architecture**: Use `app_router.dart` as the switcher to avoid redundant widget layers. | ||
| - **Isolate UI components**: Maintain specialized headers and layouts within each content screen for tailored UX. | ||
| - **Standardize filenames**: Correct naming drift (`_screen.dart` vs `_page.dart`). | ||
|
|
||
| **Non-Goals:** | ||
|
|
||
| - **Adding new content types**: We are only refactoring existing PDF, Video, and Test paths. | ||
| - **Cross-package UI sharing**: Each domain package (`courses`, `exams`) will maintain its own specialized detail UI. | ||
|
|
||
| ## Decisions | ||
|
|
||
| - **Decision 1: Use the Router as the Brain**: Instead of a "Switcher" screen, we'll map paths like `/lesson/:id` directly to specialized screens in the `app_router.dart` builder. | ||
| - **Decision 2: Standardize on `_screen.dart`**: To match your naming convention, all detail entry-point filenames will end with `_screen.dart`. | ||
| - **Decision 3: Keep UI Isolated**: PDF and Video screens will keep their own specialized headers and sidebar logic to follow the "Independent Domain" principle. | ||
|
|
||
| ## Risks / Trade-offs | ||
|
|
||
| - **Risk: Duplicate Data Loading Logic** → **Mitigation**: Use a common `lessonDetailProvider` inside the Router Builder so that fetching, loading, and error states are handled once for all types in a single location. | ||
| - **Risk: Breaking Router Paths** → **Mitigation**: Update all barrel file exports (`courses.dart`) and route definitions during the deletion of the legacy shell screen. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| ## Why | ||
|
|
||
| The current lesson detail implementation is fragmented. The `LessonDetailScreen` was overloaded with PDF-specific logic while containing placeholders for video, whereas `VideoLessonDetailScreen` exists separately with its own header/footer implementation. We need a clean way to route between different lesson content types (PDF, Video, Test, Assessment) while maintaining consistent data retrieval logic without adding unnecessary "switcher" UI layers. | ||
|
|
||
| ## What Changes | ||
|
|
||
| - **Router Orchestration**: Move content-switching logic from the widget layer into the `app_router.dart`. The router will now act as the single brain for identifying lesson types and pushing to the correct specialized screen. | ||
| - **Isolation**: Extract all PDF-specific rendering from the legacy `LessonDetailScreen` into a dedicated `PdfLessonDetailScreen`. | ||
| - **Standardization**: Rename `video_lesson_detail_page.dart` to `video_lesson_detail_screen.dart` for naming consistency. | ||
| - **Redundancy Removal**: **Delete** the redundant `LessonDetailScreen` entirely to follow the "Direct Destination Screen" pattern. | ||
|
|
||
| ## Capabilities | ||
|
|
||
| ### New Capabilities | ||
| - `lesson-router-orchestration`: A unified router-based strategy to identify lesson types (PDF, Video, etc.) and delegate rendering directly to specialized screens while sharing common data providers. | ||
|
|
||
| ### Modified Capabilities | ||
| - `lesson-pdf-playback`: Update to reflect that PDF playback now lives in its own isolated `PdfLessonDetailScreen`. | ||
|
|
||
| ## Impact | ||
|
|
||
| - `packages/courses/lib/screens/lesson_detail_screen.dart`: **Deleted** as redundant. | ||
| - `packages/courses/lib/screens/pdf_lesson_detail_screen.dart`: New file for isolated PDF rendering. | ||
| - `packages/courses/lib/screens/video_lesson_detail_screen.dart`: Standardized naming and isolated custom header. | ||
| - `packages/testpress/lib/navigation/app_router.dart`: Updated to map `/lesson/:id` directly to `PdfLessonDetailScreen`. |
19 changes: 19 additions & 0 deletions
19
openspec/changes/lesson-detail-refactor/specs/lesson-content-orchestration/spec.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| ## ADDED Requirements | ||
|
|
||
| ### Requirement: Router-Level Lesson Orchestration | ||
| The system SHALL provide a central orchestration layer within the `app_router.dart` that identifies lesson types and delegates rendering to specialized screens (PDF, Video, Test, Assessment). | ||
|
|
||
| #### Scenario: Routing to specialized PDF reader | ||
| - **WHEN** a lesson of type "pdf" is navigated to via the router | ||
| - **THEN** it SHALL be mapped directly to the `PdfLessonDetailScreen`. | ||
|
|
||
| #### Scenario: Routing to specialized Video player | ||
| - **WHEN** a lesson of type "video" is navigated to via the router | ||
| - **THEN** it SHALL be mapped directly to the `VideoLessonDetailScreen`. | ||
|
|
||
| ### Requirement: Decoupled Data Loading | ||
| The system SHALL handle the fetching of lesson domain models via `lessonDetailProvider` at the route builder level, ensuring specialized screens only receive the finished `Lesson` object. | ||
|
|
||
| #### Scenario: Unified loading indicator across types | ||
| - **WHEN** a lesson payload is being fetched for any screen | ||
| - **THEN** the router SHALL display a unified `AppLoadingIndicator`. |
9 changes: 9 additions & 0 deletions
9
openspec/changes/lesson-detail-refactor/specs/lesson-pdf-playback/spec.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| ## MODIFIED Requirements | ||
|
|
||
| ### Requirement: Remote PDF Rendering | ||
| The system SHALL support rendering PDF lessons from a remote URL via a dedicated `PdfLessonDetailScreen`. The system MUST provide a full-screen viewer which supports zooming and basic navigation for the PDF content, isolated from other content types. | ||
|
|
||
| #### Scenario: Rendering PDF content in isolated screen | ||
| - **WHEN** a lesson of type "pdf" is opened via the router-orchestrated `PdfLessonDetailScreen` | ||
| - **AND** the `contentUrl` is provided | ||
| - **THEN** the system SHALL initialize the `PdfLessonDetailScreen` and display the document in the specialized viewer. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| ## 1. Standardize Naming | ||
|
|
||
| - [x] 1.1 Rename `video_lesson_detail_page.dart` to `video_lesson_detail_screen.dart`. | ||
| - [x] 1.2 Update imports and router definitions in `packages/testpress/lib/navigation/app_router.dart` for the renamed video screen. | ||
|
|
||
| ## 2. Isolate PDF Content | ||
|
|
||
| - [x] 2.1 Create `pdf_lesson_detail_screen.dart` with state management for PDF rendering and reading progress. | ||
| - [x] 2.2 Move PDF-specific logic (AppPdfViewer) to the new screen. | ||
| - [x] 2.3 Ensure PDF screen handles its own subject-specific theme and custom header. | ||
|
|
||
| ## 3. Implement Router-First Orchestration | ||
|
|
||
| - [x] 3.1 Update `app_router.dart` builders to map `/lesson/:id` directly to `PdfLessonDetailScreen`. | ||
| - [x] 3.2 Update `app_router.dart` to share the `lessonDetailProvider` loading logic across all lesson types. | ||
| - [x] 3.3 Revert shared UI components: ensure `VideoLessonDetailScreen` keeps its own custom header. | ||
| - [x] 3.4 **Delete** the redundant `LessonDetailScreen` switcher entirely. | ||
|
|
||
| ## 4. Verification & Testing | ||
|
|
||
| - [x] 4.1 Verify that `/study/lesson/thermo-1` triggers the new `PdfLessonDetailScreen` directly. | ||
| - [x] 4.2 Verify that `/study/video/thermo-2` triggers the refactored `VideoLessonDetailScreen` directly. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.