feat: Add widgets - #70
Conversation
|
*widgets are ugly now, needs some redesign |
There was a problem hiding this comment.
Pull request overview
This PR introduces a Home Screen widget feature by adding the home_widget Flutter plugin, implementing widget data synchronization from the app’s schedule/assignments services, and adding an iOS WidgetKit extension to render that shared data.
Changes:
- Add
home_widgetdependency and corresponding iOS CocoaPods integration. - Introduce
WidgetSyncServiceand trigger widget sync fromScheduleService/AssignmentService. - Add an iOS WidgetKit extension target (SwiftUI) plus app group entitlements for data sharing.
Reviewed changes
Copilot reviewed 20 out of 22 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| pubspec.yaml | Adds home_widget dependency. |
| pubspec.lock | Adds home_widget and updates many locked dependencies + SDK metadata. |
| lib/services/widget_sync_service.dart | New service that writes schedule/assignment JSON into widget storage and triggers widget updates. |
| lib/services/schedule_service.dart | Calls widget sync after loading cached schedule and after fetching course table. |
| lib/services/assignment_service.dart | Calls widget sync after loading cached assignments, persisting overrides, and after fetch/merge flows. |
| ios/TechPieWidgetExtension.entitlements | Adds app group entitlement for the widget extension. |
| ios/TechPieWidget/TechPieWidgetBundle.swift | Declares the widget bundle entry point. |
| ios/TechPieWidget/TechPieWidget.swift | Implements WidgetKit timeline + SwiftUI views and reads shared JSON from app group defaults. |
| ios/TechPieWidget/Info.plist | Adds widget extension Info.plist with WidgetKit extension point identifier. |
| ios/TechPieWidget/Assets.xcassets/WidgetBackground.colorset/Contents.json | Adds widget asset catalog entry. |
| ios/TechPieWidget/Assets.xcassets/Contents.json | Adds widget asset catalog root metadata. |
| ios/TechPieWidget/Assets.xcassets/AppIcon.appiconset/Contents.json | Adds widget extension app icon catalog metadata. |
| ios/TechPieWidget/Assets.xcassets/AccentColor.colorset/Contents.json | Adds accent color asset catalog metadata. |
| ios/Runner/Runner.entitlements | Adds app group entitlement for the main iOS app. |
| ios/Runner/NativeGlass/NativeNavigationBar.swift | Adds compiler guards around newer iOS API usage. |
| ios/Runner/NativeGlass/NativeGlassSelect.swift | Adds compiler-conditional fallback configuration for older compilers. |
| ios/Runner/NativeGlass/NativeGlassDropdownMenu.swift | Adds compiler-conditional fallback configuration for older compilers. |
| ios/Runner/NativeGlass/NativeGlassConfirmationButton.swift | Adds compiler-conditional fallback configuration for older compilers. |
| ios/Runner/NativeGlass/NativeGlassButton.swift | Adds compiler-conditional fallback configuration for older compilers. |
| ios/Runner.xcodeproj/project.pbxproj | Adds widget extension target, embeds extension, sets entitlements, and bumps iOS deployment target to 14.0. |
| ios/Podfile.lock | Adds home_widget pod and updates pod checksums. |
| ios/Podfile | Raises iOS platform minimum to 14.0. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Convert to display courses, filtering for current week | ||
| final displayCourses = eamsToDisplayCourses(table.courses, currentWeek); | ||
|
|
||
| // Get today's active courses, sorted by period | ||
| final todayCourses = displayCourses | ||
| .where((c) => c.dayOfWeek == weekday && !c.isGhost) | ||
| .toList(); | ||
| todayCourses.sort((a, b) => a.startPeriod.compareTo(b.startPeriod)); | ||
|
|
||
| final coursesJson = todayCourses.map((c) { | ||
| final startTime = defaultPeriods.firstWhere((p) => p.number == c.startPeriod, orElse: () => const Period(number: 0, startTime: '', endTime: '')).startTime; | ||
| final endTime = defaultPeriods.firstWhere((p) => p.number == c.endPeriod, orElse: () => const Period(number: 0, startTime: '', endTime: '')).endTime; | ||
| return { | ||
| 'name': c.name, | ||
| 'location': c.location, | ||
| 'startTime': startTime, | ||
| 'endTime': endTime, | ||
| }; | ||
| }).toList(); |
| import 'dart:convert'; | ||
|
|
||
| import 'package:home_widget/home_widget.dart'; | ||
|
|
| await HomeWidget.setAppGroupId(_groupId); | ||
| await HomeWidget.saveWidgetData('schedule_data', jsonEncode(coursesJson)); | ||
| await HomeWidget.updateWidget(name: 'TechPieWidget', iOSName: 'TechPieWidget'); |
| await HomeWidget.setAppGroupId(_groupId); | ||
| await HomeWidget.saveWidgetData('assignment_data', jsonEncode(assignmentsJson)); | ||
| await HomeWidget.updateWidget(name: 'TechPieWidget', iOSName: 'TechPieWidget'); |
| void _syncWidget() { | ||
| if (_courseTable != null) { | ||
| try { | ||
| unawaited(WidgetSyncService.syncSchedule(_courseTable!, currentWeek())); | ||
| } catch (_) {} | ||
| } | ||
| } |
| void _syncWidget() { | ||
| try { | ||
| unawaited(WidgetSyncService.syncAssignments(_assignments, _overrides)); | ||
| } catch (_) {} | ||
| } |
| let nextUpdate = Calendar.current.date(byAdding: .minute, value: 30, to: Date())! | ||
| let timeline = Timeline(entries: [entry], policy: .after(nextUpdate)) |
| MARKETING_VERSION = 1.0; | ||
| MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; | ||
| MTL_FAST_MATH = YES; | ||
| PRODUCT_BUNDLE_IDENTIFIER = com.example.techpie.TechPieWidget; |
There was a problem hiding this comment.
@CNDY1390 Does this require additional configuration in CD?
| import '../models/course_table.dart'; | ||
|
|
||
| class WidgetSyncService { | ||
| static const String _groupId = 'group.com.example.techpie'; |
There was a problem hiding this comment.
Same as above. Do we need to write it all in a single configuration?
Honahec
left a comment
There was a problem hiding this comment.
Widget seems to be working properly.
Only CD problem remaining.
No description provided.