-
Notifications
You must be signed in to change notification settings - Fork 0
Convert web application to Flutter mobile app #14
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
Convert web application to Flutter mobile app #14
Conversation
- Add Flutter project structure with pubspec.yaml and dependencies - Implement models: LessonDay, SupplementaryContent, VideoInfo - Create services: ContentService for loading lessons, ProgressService for tracking - Build screens: DashboardScreen, LessonScreen, SupplementaryScreen - Add audio playback support using audioplayers package - Integrate YouTube video player for lesson videos - Implement progress tracking with shared_preferences - Support RTL text rendering for Arabic with custom theming - Create trilingual interface (Arabic, transliteration, English) - Maintain offline-first architecture with local asset loading - Update README with Flutter setup instructions - Add Flutter-specific gitignore rules - Add linting configuration with analysis_options.yaml The Flutter app provides the same 40-day Arabic learning curriculum with improved mobile UX, offline support, and native performance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds a Flutter mobile application implementation to the existing Arabic language learning platform, transforming it from a web-only solution to a cross-platform mobile app with offline-first capabilities.
Key Changes:
- Flutter mobile application with screens for dashboard, lessons, and supplementary content
- Offline-first architecture with local storage for progress tracking
- Audio playback and YouTube video integration for interactive learning
Reviewed Changes
Copilot reviewed 14 out of 15 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| pubspec.yaml | Defines Flutter project dependencies including audio players, YouTube player, and state management |
| lib/main.dart | Application entry point with theme configuration and orientation setup |
| lib/models/*.dart | Data models for lessons, supplementary content, and video information |
| lib/services/*.dart | Business logic for content loading and progress tracking |
| lib/screens/*.dart | UI screens for dashboard, lessons, and supplementary content |
| lib/utils/app_theme.dart | Centralized theme configuration with level-based color coding |
| README.md | Updated documentation covering Flutter setup and mobile features |
| .gitignore | Modified to support Flutter/Dart tooling while maintaining Python compatibility |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| _audioPlayer.onPlayerComplete.listen((_) { | ||
| setState(() { | ||
| _isPlayingArabic = false; | ||
| _isPlayingEnglish = false; | ||
| }); | ||
| }); |
Copilot
AI
Nov 8, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Memory leak: A new stream subscription is created every time audio is played without canceling the previous one. Store the StreamSubscription in a field and cancel it before creating a new one, or cancel it in dispose().
| _audioPlayer.onPlayerComplete.listen((_) { | ||
| setState(() { | ||
| _isPlayingArabic = false; | ||
| _isPlayingEnglish = false; | ||
| }); | ||
| }); |
Copilot
AI
Nov 8, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Memory leak: A new stream subscription is created every time audio is played without canceling the previous one. Store the StreamSubscription in a field and cancel it before creating a new one, or cancel it in dispose().
| final String arabicAudioPath; | ||
| final String englishAudioPath; | ||
| final String? videoId; | ||
| final String level; |
Copilot
AI
Nov 8, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The 'level' field is required but never populated in ContentService.loadDay() (line 66 sets level to empty string ''). Either make this field nullable/optional, remove it, or properly populate it from the level name logic that already exists in the levelName getter.
| final days = <LessonDay>[]; | ||
| for (int i = 1; i <= 40; i++) { | ||
| days.add(await loadDay(i)); | ||
| } | ||
| return days; |
Copilot
AI
Nov 8, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Loading all 40 days sequentially with await in a loop is inefficient. Use Future.wait() to load all days concurrently: await Future.wait(List.generate(40, (i) => loadDay(i + 1))) to significantly improve performance.
| final days = <LessonDay>[]; | |
| for (int i = 1; i <= 40; i++) { | |
| days.add(await loadDay(i)); | |
| } | |
| return days; | |
| return await Future.wait( | |
| List.generate(40, (i) => loadDay(i + 1)), | |
| ); |
| static Color getLevelColor(int dayNumber) { | ||
| if (dayNumber <= 7) return primaryColor; | ||
| if (dayNumber <= 14) return secondaryColor; | ||
| if (dayNumber <= 22) return accentColor; | ||
| if (dayNumber <= 30) return purpleColor; | ||
| return orangeColor; | ||
| } |
Copilot
AI
Nov 8, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The level logic (days 1-7, 8-14, 15-22, 23-30, 31-40) is duplicated in three places: AppTheme.getLevelColor(), AppTheme.getLevelName(), and LessonDay.levelName. Consider consolidating this into a single Level enum or model to maintain consistency and avoid bugs if boundaries change.
The Flutter app provides the same 40-day Arabic learning curriculum
with improved mobile UX, offline support, and native performance.