diff --git a/lib/body.dart b/lib/body.dart index 157ba25..08c8e42 100644 --- a/lib/body.dart +++ b/lib/body.dart @@ -1,7 +1,11 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:package_info_plus/package_info_plus.dart'; +import 'package:provider/provider.dart'; +import 'providers/saved_schedule_provider.dart'; +import 'saved_schedule_selector.dart'; import 'util/launcher_url.dart'; import 'views/course browser/browser.dart'; import 'views/scheduler/schedule_maker.dart'; @@ -21,6 +25,11 @@ class MyBody extends StatelessWidget { return Scaffold( extendBodyBehindAppBar: true, appBar: AppBar( + systemOverlayStyle: Theme.of(context).brightness == Brightness.light + ? SystemUiOverlayStyle.dark + .copyWith(statusBarColor: Colors.grey.withAlpha(90)) + : SystemUiOverlayStyle.light + .copyWith(statusBarColor: Colors.grey.withAlpha(90)), shadowColor: Colors.transparent, backgroundColor: Colors.transparent, foregroundColor: Colors.transparent, @@ -50,9 +59,9 @@ class MyBody extends StatelessWidget { default: } }, - icon: const Icon( + icon: Icon( Icons.more_vert_outlined, - color: Colors.black87, + color: Theme.of(context).iconTheme.color!, ), itemBuilder: (context) => const [ PopupMenuItem( @@ -74,9 +83,12 @@ class MyBody extends StatelessWidget { 'Schedule Maker', style: _textStyle, ), - onPressed: () { - Navigator.of(context) + onPressed: () async { + // SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark); + await Navigator.of(context) .push(CupertinoPageRoute(builder: (_) => ScheduleMaker())); + + // SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark); }, ), ), @@ -94,6 +106,42 @@ class MyBody extends StatelessWidget { }, ), ), + const Divider(), + Consumer( + builder: (_, value, __) { + if (value.data.isEmpty) { + return const Padding( + padding: EdgeInsets.symmetric(vertical: 4), + child: Text( + "Your saved schedule will appear here", + textAlign: TextAlign.center, + style: TextStyle(fontWeight: FontWeight.w300), + ), + ); + } + if (value.data.isNotEmpty) { + return Column( + children: [ + MouseRegion( + cursor: SystemMouseCursors.click, + child: CupertinoButton( + child: Text( + 'Saved Schedule', + style: _textStyle, + ), + onPressed: () { + Navigator.of(context).push(CupertinoPageRoute( + builder: (_) => const SavedScheduleSelector())); + }, + ), + ), + ], + ); + } else { + return const SizedBox.shrink(); + } + }, + ), ], ), ); diff --git a/lib/constant.dart b/lib/colour_palletes.dart similarity index 100% rename from lib/constant.dart rename to lib/colour_palletes.dart diff --git a/lib/constants.dart b/lib/constants.dart new file mode 100644 index 0000000..faf01cf --- /dev/null +++ b/lib/constants.dart @@ -0,0 +1 @@ +const kHiveSavedSchedule = "savedSchedule"; diff --git a/lib/main.dart b/lib/main.dart index 83f260c..08f2962 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,9 +1,16 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:hive_flutter/hive_flutter.dart'; +import 'package:provider/provider.dart'; import 'body.dart'; +import 'constants.dart'; +import 'providers/saved_schedule_provider.dart'; + +void main() async { + await Hive.initFlutter(); + await Hive.openBox(kHiveSavedSchedule); -void main() { runApp(const MyApp()); } @@ -12,17 +19,22 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { - return MaterialApp( - title: 'IIUM Schedule (Preview)', - theme: ThemeData( - primarySwatch: Colors.purple, - ), - darkTheme: ThemeData.dark().copyWith( - cupertinoOverrideTheme: - const CupertinoThemeData(primaryColor: Colors.purple), + return MultiProvider( + providers: [ + ChangeNotifierProvider(create: (_) => SavedScheduleProvider()), + ], + child: MaterialApp( + title: 'IIUM Schedule (Preview)', + theme: ThemeData( + primarySwatch: Colors.purple, + ), + darkTheme: ThemeData.dark().copyWith( + cupertinoOverrideTheme: + const CupertinoThemeData(primaryColor: Colors.purple), + ), + themeMode: ThemeMode.system, + home: const MyBody(), ), - themeMode: ThemeMode.system, - home: const MyBody(), ); } } diff --git a/lib/providers/saved_schedule_provider.dart b/lib/providers/saved_schedule_provider.dart new file mode 100644 index 0000000..20feba3 --- /dev/null +++ b/lib/providers/saved_schedule_provider.dart @@ -0,0 +1,22 @@ +import 'dart:convert'; + +import 'package:flutter/foundation.dart'; +import 'package:hive/hive.dart'; + +import '../constants.dart'; + +class SavedScheduleProvider extends ChangeNotifier { + final _box = Hive.box(kHiveSavedSchedule); + + /// oldName is needed to detect is schedule is renamed, + /// if it is, the key with `oldName` will be deleted + /// and a new schedule will be saved in the new key (`name`) + void setSchedule( + {required String name, required List data, String? oldName}) { + if ((oldName != null) || (oldName == name)) _box.delete(oldName); + _box.put(name, jsonEncode(data)); + notifyListeners(); + } + + Box get data => _box; +} diff --git a/lib/saved_schedule_selector.dart b/lib/saved_schedule_selector.dart new file mode 100644 index 0000000..9ab7719 --- /dev/null +++ b/lib/saved_schedule_selector.dart @@ -0,0 +1,93 @@ +import 'dart:convert'; + +import 'package:albiruni/albiruni.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:hive/hive.dart'; + +import 'constants.dart'; +import 'views/scheduler/schedule_layout.dart'; + +class SavedScheduleSelector extends StatefulWidget { + const SavedScheduleSelector({Key? key}) : super(key: key); + + @override + State createState() => _SavedScheduleSelectorState(); +} + +class _SavedScheduleSelectorState extends State { + final box = Hive.box(kHiveSavedSchedule); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text( + "Saved schedule", + ), + systemOverlayStyle: SystemUiOverlayStyle.light + .copyWith(statusBarColor: Colors.transparent), + ), + body: ListView.builder( + padding: const EdgeInsets.all(8), + itemCount: box.length, + itemBuilder: (context, index) { + var name = box.keyAt(index); + var data = box.getAt(index); + return Card( + child: ListTile( + title: Text(name), + trailing: IconButton( + icon: const Icon( + Icons.delete_outline, + color: Colors.redAccent, + ), + onPressed: () { + showDialog( + context: context, + builder: (_) => AlertDialog( + title: const Text("Confirm delete"), + actions: [ + OutlinedButton( + onPressed: () => Navigator.pop(context), + child: const Text("Cancel"), + ), + ElevatedButton( + style: ElevatedButton.styleFrom( + primary: Colors.redAccent), + onPressed: () { + Navigator.pop(context); + setState(() => box.deleteAt(index)); + }, + child: const Text("Delete"), + ), + ], + ), + ); + }, + ), + onTap: () async { + List parsedListJson = jsonDecode(data); + await Navigator.push( + context, + CupertinoPageRoute( + builder: (_) => ScheduleLayout( + initialName: name, + subjects: List.from( + parsedListJson.map((e) => Subject.fromJson(e)), + ), + ), + ), + ); + + // refresh page when come back to thus screen + setState(() {}); + }, + ), + ); + }, + ), + ); + } +} diff --git a/lib/util/course_validator_pass.dart b/lib/util/course_validator_pass.dart index e801ade..3e736ce 100644 --- a/lib/util/course_validator_pass.dart +++ b/lib/util/course_validator_pass.dart @@ -25,5 +25,6 @@ class CourseValidatorPass { return _status.where((element) => !element).length; } + //TODO: Why need map in this situation List fetchedSubjects() => _subjects.map((e) => e!).toList(); } diff --git a/lib/views/course browser/browser.dart b/lib/views/course browser/browser.dart index 6f098f6..26404ca 100644 --- a/lib/views/course browser/browser.dart +++ b/lib/views/course browser/browser.dart @@ -2,6 +2,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:albiruni/albiruni.dart'; +import 'package:flutter/services.dart'; import 'browser_view.dart'; @@ -38,6 +39,8 @@ class _BrowserState extends State { onTap: () => FocusScope.of(context).unfocus(), child: Scaffold( appBar: AppBar( + systemOverlayStyle: SystemUiOverlayStyle.light + .copyWith(statusBarColor: Colors.transparent), title: const Text('Course Browser'), ), body: Center( @@ -98,6 +101,8 @@ class _BrowserState extends State { child: CupertinoTextField( maxLength: 9, controller: _searchController, + // https://github.com/flutter/flutter/issues/48438#issuecomment-621262652 + style: CupertinoTheme.of(context).textTheme.textStyle, placeholder: "Search subject", clearButtonMode: OverlayVisibilityMode.editing, selectionControls: MaterialTextSelectionControls(), diff --git a/lib/views/course browser/browser_view.dart b/lib/views/course browser/browser_view.dart index 33c5638..1b9c2d4 100644 --- a/lib/views/course browser/browser_view.dart +++ b/lib/views/course browser/browser_view.dart @@ -37,6 +37,7 @@ class _BrowserViewState extends State { "${widget.kulliyah} Sem ${widget.albiruni.semester} ${widget.albiruni.session}"), actions: [ IconButton( + tooltip: "Prevous page", onPressed: _page <= 1 ? null : () { @@ -45,6 +46,7 @@ class _BrowserViewState extends State { icon: const Icon(Icons.navigate_before_outlined)), Center(child: Text(_page.toString())), IconButton( + tooltip: "Next page", onPressed: () { setState(() { setState(() => _page++); diff --git a/lib/views/scheduler/course_validator.dart b/lib/views/scheduler/course_validator.dart index ded449a..3f4e3ba 100644 --- a/lib/views/scheduler/course_validator.dart +++ b/lib/views/scheduler/course_validator.dart @@ -2,12 +2,13 @@ import 'package:albiruni/albiruni.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:recase/recase.dart'; + +import '../../model/basic_subject_model.dart'; import '../../util/course_validator_pass.dart'; -import 'schedule_maker_data.dart'; import '../course%20browser/subject_screen.dart'; import 'schedule_layout.dart'; -import 'package:recase/recase.dart'; -import '../../model/basic_subject_model.dart'; +import 'schedule_maker_data.dart'; CourseValidatorPass? _validatorPass; @@ -61,7 +62,10 @@ class _CourseValidatorState extends State Navigator.of(context).push(CupertinoPageRoute( builder: (_) => ScheduleLayout( - _validatorPass!.fetchedSubjects()))); + initialName: + '${ScheduleMakerData.kulliyah} ${ScheduleMakerData.albiruni!.semester} ${ScheduleMakerData.albiruni!.session}', + subjects: _validatorPass!.fetchedSubjects(), + ))); }, child: const Text("Proceed"), ), diff --git a/lib/views/scheduler/input_course.dart b/lib/views/scheduler/input_course.dart index c819193..5e84a6d 100644 --- a/lib/views/scheduler/input_course.dart +++ b/lib/views/scheduler/input_course.dart @@ -341,7 +341,7 @@ class _InputCourseState extends State if (_inputIndex == 1) Link( uri: Uri.parse( - "https://iiumschedule.vercel.app/docs/extract/imaalum"), + "https://iiumschedule.vercel.app/docs/extract/imaluum"), target: LinkTarget.blank, builder: (_, followLink) => TextButton( onPressed: followLink, diff --git a/lib/views/scheduler/schedule_layout.dart b/lib/views/scheduler/schedule_layout.dart index 343c0cb..51fb789 100644 --- a/lib/views/scheduler/schedule_layout.dart +++ b/lib/views/scheduler/schedule_layout.dart @@ -1,16 +1,20 @@ -import 'dart:io'; - import 'package:albiruni/albiruni.dart'; -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_timetable_view/flutter_timetable_view.dart'; +import 'package:fluttertoast/fluttertoast.dart'; +import 'package:provider/provider.dart'; -import '../../constant.dart'; +import '../../colour_palletes.dart'; +import '../../providers/saved_schedule_provider.dart'; import '../../util/extensions.dart'; class ScheduleLayout extends StatefulWidget { - const ScheduleLayout(this.subjects, {Key? key}) : super(key: key); + const ScheduleLayout( + {Key? key, required this.initialName, required this.subjects}) + : super(key: key); + final String initialName; final List subjects; @override @@ -19,13 +23,29 @@ class ScheduleLayout extends StatefulWidget { class _ScheduleLayoutState extends State { final _colorPallete = [...ColourPallete.pallete1]; // add more - int startHour = 10; // pukul 10 am - int endHour = 17; // pukul 5 pm + int _startHour = 10; // pukul 10 am + int _endHour = 17; // pukul 5 pm + + double _itemHeight = 60.0; + + late String name; + + bool _isFullScreen = false; + bool _hideFab = false; @override void initState() { super.initState(); _colorPallete.shuffle(); + name = widget.initialName; + } + + void save() { + var scheduleData = widget.subjects.map((e) => e.toJson()).toList(); + + Provider.of(context, listen: false).setSchedule( + name: name, data: scheduleData, oldName: widget.initialName); + Fluttertoast.showToast(msg: "Saved"); } @override @@ -63,9 +83,9 @@ class _ScheduleLayoutState extends State { hour: int.parse(e.dayTime.first!.endTime.split(":").first), minute: int.parse(e.dayTime.first!.endTime.split(":").last)); - if (_start.hour < startHour) startHour = _start.hour; + if (_start.hour < _startHour) _startHour = _start.hour; - if (_end.hour > endHour) endHour = _end.hour; + if (_end.hour > _endHour) _endHour = _end.hour; // choose same and unique colour to each subject var subjIndex = @@ -79,19 +99,11 @@ class _ScheduleLayoutState extends State { textStyle: TextStyle(fontSize: 10, color: textColor), title: e.title, backgroundColor: _colorPallete[subjIndex], - start: TableEventTime( - hour: _start.hour, - minute: _start.minute, - ), - end: TableEventTime( - hour: _end.hour, - minute: _end.minute, - ), + start: TableEventTime(hour: _start.hour, minute: _start.minute), + end: TableEventTime(hour: _end.hour, minute: _end.minute), onTap: () => showDialog( context: context, - builder: (context) => AlertDialog( - content: Text(e.code), - ), + builder: (_) => AlertDialog(content: Text(e.code)), ), ); }, @@ -120,35 +132,136 @@ class _ScheduleLayoutState extends State { break; } } - return Scaffold( - appBar: (kIsWeb || !Platform.isAndroid) - ? AppBar( - title: const Text("Timetable"), - ) - : null, - body: SafeArea( - child: TimetableViewWidget( - startHour: startHour, - endHour: endHour, - laneEventsList: _laneEventsList), + return GestureDetector( + onTap: _hideFab ? () => setState(() => _hideFab = !_hideFab) : null, + child: Scaffold( + appBar: _isFullScreen + ? null + : AppBar( + title: InkWell( + onTap: () async { + final _scheduleNameController = + TextEditingController(text: name); + String? newName = await showDialog( + context: context, + builder: (_) => RenameDialog( + scheduleNameController: _scheduleNameController)); + + if ((newName == null) || (newName.isEmpty)) return; + + setState(() => name = newName); + save(); + }, + child: Text(name)), + actions: [ + IconButton( + tooltip: "Save", + onPressed: save, + icon: const Icon(Icons.save), + ), + ], + ), + body: SafeArea( + child: Padding( + padding: const EdgeInsets.only(top: 8), + child: TimetableViewWidget( + startHour: _startHour, + endHour: _endHour, + laneEventsList: _laneEventsList, + itemHeight: _itemHeight, + ), + ), + ), + floatingActionButton: _hideFab + ? null + : Column( + mainAxisSize: MainAxisSize.min, + children: [ + if (_itemHeight <= 90) + FloatingActionButton( + heroTag: "btnZoom+", + mini: true, + child: const Icon(Icons.zoom_in), + onPressed: () { + setState(() => _itemHeight += 2); + }), + if (_itemHeight >= 52) + FloatingActionButton( + heroTag: "btnZoom-", + mini: true, + child: const Icon(Icons.zoom_out), + onPressed: () { + setState(() => _itemHeight -= 2); + }), + FloatingActionButton( + heroTag: "btnFull", + mini: true, + onPressed: fullscreenFabHandler, + child: Icon(_isFullScreen + ? Icons.fullscreen_exit + : Icons.fullscreen), + ), + ], + ), ), ); } + + void fullscreenFabHandler() { + if (!_isFullScreen) { + SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive); + setState(() { + _isFullScreen = true; + _hideFab = true; + }); + } else { + SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge); + setState(() => _isFullScreen = false); + } + } } -class TimetableViewWidget extends StatelessWidget { - const TimetableViewWidget({ +class RenameDialog extends StatelessWidget { + const RenameDialog({ Key? key, - required this.startHour, - required this.endHour, - required List laneEventsList, - }) : _laneEventsList = laneEventsList, + required TextEditingController scheduleNameController, + }) : _scheduleNameController = scheduleNameController, + super(key: key); + + final TextEditingController _scheduleNameController; + + @override + Widget build(BuildContext context) { + return AlertDialog( + title: const Text("Rename"), + content: TextField(controller: _scheduleNameController), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: const Text("Cancel")), + TextButton( + onPressed: () => Navigator.pop(context, _scheduleNameController.text), + child: const Text("Rename"), + ), + ], + ); + } +} + +class TimetableViewWidget extends StatelessWidget { + const TimetableViewWidget( + {Key? key, + required this.startHour, + required this.endHour, + required List laneEventsList, + required this.itemHeight}) + : _laneEventsList = laneEventsList, super(key: key); final int startHour; final int endHour; final List _laneEventsList; - + final double itemHeight; @override Widget build(BuildContext context) { return LayoutBuilder(builder: (_, constraints) { @@ -158,6 +271,8 @@ class TimetableViewWidget extends StatelessWidget { ? Colors.black38 : Colors.white38, timeItemWidth: 50, + laneHeight: 20, + timeItemHeight: itemHeight, laneWidth: constraints.maxWidth / (_laneEventsList.length + .8), // responsive layout while providing little padding at the end diff --git a/lib/views/scheduler/schedule_maker.dart b/lib/views/scheduler/schedule_maker.dart index ccd9f3c..4ab9b33 100644 --- a/lib/views/scheduler/schedule_maker.dart +++ b/lib/views/scheduler/schedule_maker.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:page_view_indicators/page_view_indicators.dart'; import 'appbar_title.dart'; @@ -45,6 +46,8 @@ class ScheduleMaker extends StatelessWidget { }, child: Scaffold( appBar: AppBar( + systemOverlayStyle: SystemUiOverlayStyle.light + .copyWith(statusBarColor: Colors.transparent), centerTitle: true, leading: IconButton( icon: const Icon(Icons.arrow_back), diff --git a/pubspec.lock b/pubspec.lock index ebd5ed2..bc835fd 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,13 +1,27 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + url: "https://pub.dartlang.org" + source: hosted + version: "36.0.0" albiruni: dependency: "direct main" description: path: "../../Dart App/albiruni" relative: true source: path - version: "1.0.2" + version: "1.1.2" + analyzer: + dependency: transitive + description: + name: analyzer + url: "https://pub.dartlang.org" + source: hosted + version: "3.3.1" and: dependency: "direct main" description: @@ -45,6 +59,62 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0" + build: + dependency: transitive + description: + name: build + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.1" + build_config: + dependency: transitive + description: + name: build_config + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + build_daemon: + dependency: transitive + description: + name: build_daemon + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" + build_resolvers: + dependency: transitive + description: + name: build_resolvers + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.6" + build_runner: + dependency: "direct dev" + description: + name: build_runner + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.7" + build_runner_core: + dependency: transitive + description: + name: build_runner_core + url: "https://pub.dartlang.org" + source: hosted + version: "7.2.3" + built_collection: + dependency: transitive + description: + name: built_collection + url: "https://pub.dartlang.org" + source: hosted + version: "5.1.1" + built_value: + dependency: transitive + description: + name: built_value + url: "https://pub.dartlang.org" + source: hosted + version: "8.1.4" characters: dependency: transitive description: @@ -59,6 +129,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.3.1" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" clock: dependency: transitive description: @@ -66,6 +143,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.0" + code_builder: + dependency: transitive + description: + name: code_builder + url: "https://pub.dartlang.org" + source: hosted + version: "4.1.0" collection: dependency: transitive description: @@ -73,6 +157,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.15.0" + convert: + dependency: transitive + description: + name: convert + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" csslib: dependency: transitive description: @@ -87,6 +185,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.2" + dart_style: + dependency: transitive + description: + name: dart_style + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.2" fake_async: dependency: transitive description: @@ -101,6 +206,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.2" + file: + dependency: transitive + description: + name: file + url: "https://pub.dartlang.org" + source: hosted + version: "6.1.2" + fixnum: + dependency: transitive + description: + name: fixnum + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" flutter: dependency: "direct main" description: flutter @@ -121,7 +240,7 @@ packages: flutter_timetable_view: dependency: "direct main" description: - path: "../Experiments/flutter_timetable_view-1" + path: "../Experiments/flutter_timetable_view" relative: true source: path version: "0.2.0" @@ -130,6 +249,55 @@ packages: description: flutter source: sdk version: "0.0.0" + fluttertoast: + dependency: "direct main" + description: + name: fluttertoast + url: "https://pub.dartlang.org" + source: hosted + version: "8.0.9" + frontend_server_client: + dependency: transitive + description: + name: frontend_server_client + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.2" + glob: + dependency: transitive + description: + name: glob + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" + graphs: + dependency: transitive + description: + name: graphs + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + hive: + dependency: "direct main" + description: + name: hive + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.6" + hive_flutter: + dependency: "direct main" + description: + name: hive_flutter + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + hive_generator: + dependency: "direct dev" + description: + name: hive_generator + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.2" html: dependency: "direct main" description: @@ -144,6 +312,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.13.4" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + url: "https://pub.dartlang.org" + source: hosted + version: "3.2.0" http_parser: dependency: transitive description: @@ -165,6 +340,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.17.0" + io: + dependency: transitive + description: + name: io + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" js: dependency: transitive description: @@ -172,6 +354,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.6.3" + json_annotation: + dependency: transitive + description: + name: json_annotation + url: "https://pub.dartlang.org" + source: hosted + version: "4.4.0" lints: dependency: transitive description: @@ -179,6 +368,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.1" + logging: + dependency: transitive + description: + name: logging + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" matcher: dependency: transitive description: @@ -200,6 +396,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.7.0" + mime: + dependency: transitive + description: + name: mime + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" msix: dependency: "direct dev" description: @@ -207,6 +410,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.6.5" + nested: + dependency: transitive + description: + name: nested + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" package_config: dependency: transitive description: @@ -270,6 +480,62 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.8.0" + path_provider: + dependency: transitive + description: + name: path_provider + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.9" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.12" + path_provider_ios: + dependency: transitive + description: + name: path_provider_ios + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.8" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.5" + path_provider_macos: + dependency: transitive + description: + name: path_provider_macos + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.5" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.5" + platform: + dependency: transitive + description: + name: platform + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" plugin_platform_interface: dependency: transitive description: @@ -277,6 +543,41 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.2" + pool: + dependency: transitive + description: + name: pool + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" + process: + dependency: transitive + description: + name: process + url: "https://pub.dartlang.org" + source: hosted + version: "4.2.4" + provider: + dependency: "direct main" + description: + name: provider + url: "https://pub.dartlang.org" + source: hosted + version: "6.0.2" + pub_semver: + dependency: transitive + description: + name: pub_semver + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" recase: dependency: "direct main" description: @@ -284,11 +585,39 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "4.0.0" + shelf: + dependency: transitive + description: + name: shelf + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" sky_engine: dependency: transitive description: flutter source: sdk version: "0.0.99" + source_gen: + dependency: transitive + description: + name: source_gen + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.1" + source_helper: + dependency: transitive + description: + name: source_helper + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.1" source_span: dependency: transitive description: @@ -310,6 +639,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0" + stream_transform: + dependency: transitive + description: + name: stream_transform + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" string_scanner: dependency: transitive description: @@ -331,6 +667,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.4.8" + timing: + dependency: transitive + description: + name: timing + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" typed_data: dependency: transitive description: @@ -401,6 +744,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.1" + watcher: + dependency: transitive + description: + name: watcher + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" win32: dependency: transitive description: @@ -408,6 +765,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.3.1" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.0+1" yaml: dependency: transitive description: @@ -417,4 +781,4 @@ packages: version: "3.1.0" sdks: dart: ">=2.14.0 <3.0.0" - flutter: ">=2.5.0" + flutter: ">=2.8.0" diff --git a/pubspec.yaml b/pubspec.yaml index 3b6552a..29ea86e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: flutter_iium_schedule -description: IIUM Schedule Parser with Flutter +description: IIUM Schedule Maker # The following line prevents the package from being accidentally published to # pub.dev using `pub publish`. This is preferred for private packages. @@ -15,7 +15,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0-rc.1+4 +version: 1.0.0-rc.2+5 environment: sdk: ">=2.12.0 <3.0.0" @@ -38,19 +38,25 @@ dependencies: flutter_timetable_view: git: https://github.com/iqfareez/flutter_timetable_view.git page_view_indicators: ^2.0.0 + hive: ^2.0.6 + hive_flutter: ^1.1.0 + provider: ^6.0.2 + fluttertoast: ^8.0.9 # Comment this part if necessary dependency_overrides: albiruni: path: "../../Dart App/albiruni" flutter_timetable_view: - path: "../Experiments/flutter_timetable_view-1" + path: "../Experiments/flutter_timetable_view" dev_dependencies: flutter_test: sdk: flutter msix: ^2.6.5 + build_runner: ^2.1.7 + hive_generator: ^1.1.2 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec @@ -96,7 +102,7 @@ msix_config: display_name: IIUM Schedule publisher_display_name: Muhammad Fareez Iqmal identity_name: fareez.flutter.iiumschedule - msix_version: 0.1.0.0 + msix_version: 0.1.0.2 logo_path: ".\\assets\\logo\\app-logo.png" capabilities: "internetClient" certificate_path: "C:\\Users\\Iqmal\\CERTIFICATE.pfx"