Skip to content

Commit

Permalink
🔖 RC2 1.0.0-rc.2+5
Browse files Browse the repository at this point in the history
  • Loading branch information
iqfareez committed Mar 12, 2022
1 parent 1c1c46b commit 3b85d96
Show file tree
Hide file tree
Showing 15 changed files with 741 additions and 65 deletions.
56 changes: 52 additions & 4 deletions lib/body.dart
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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,
Expand Down Expand Up @@ -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(
Expand All @@ -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);
},
),
),
Expand All @@ -94,6 +106,42 @@ class MyBody extends StatelessWidget {
},
),
),
const Divider(),
Consumer<SavedScheduleProvider>(
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();
}
},
),
],
),
);
Expand Down
File renamed without changes.
1 change: 1 addition & 0 deletions lib/constants.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
const kHiveSavedSchedule = "savedSchedule";
34 changes: 23 additions & 11 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -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());
}

Expand All @@ -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(),
);
}
}
22 changes: 22 additions & 0 deletions lib/providers/saved_schedule_provider.dart
Original file line number Diff line number Diff line change
@@ -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<dynamic> data, String? oldName}) {
if ((oldName != null) || (oldName == name)) _box.delete(oldName);
_box.put(name, jsonEncode(data));
notifyListeners();
}

Box get data => _box;
}
93 changes: 93 additions & 0 deletions lib/saved_schedule_selector.dart
Original file line number Diff line number Diff line change
@@ -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<SavedScheduleSelector> createState() => _SavedScheduleSelectorState();
}

class _SavedScheduleSelectorState extends State<SavedScheduleSelector> {
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<dynamic> parsedListJson = jsonDecode(data);
await Navigator.push(
context,
CupertinoPageRoute(
builder: (_) => ScheduleLayout(
initialName: name,
subjects: List<Subject>.from(
parsedListJson.map((e) => Subject.fromJson(e)),
),
),
),
);

// refresh page when come back to thus screen
setState(() {});
},
),
);
},
),
);
}
}
1 change: 1 addition & 0 deletions lib/util/course_validator_pass.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@ class CourseValidatorPass {
return _status.where((element) => !element).length;
}

//TODO: Why need map in this situation
List<Subject> fetchedSubjects() => _subjects.map((e) => e!).toList();
}
5 changes: 5 additions & 0 deletions lib/views/course browser/browser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -38,6 +39,8 @@ class _BrowserState extends State<Browser> {
onTap: () => FocusScope.of(context).unfocus(),
child: Scaffold(
appBar: AppBar(
systemOverlayStyle: SystemUiOverlayStyle.light
.copyWith(statusBarColor: Colors.transparent),
title: const Text('Course Browser'),
),
body: Center(
Expand Down Expand Up @@ -98,6 +101,8 @@ class _BrowserState extends State<Browser> {
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(),
Expand Down
2 changes: 2 additions & 0 deletions lib/views/course browser/browser_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class _BrowserViewState extends State<BrowserView> {
"${widget.kulliyah} Sem ${widget.albiruni.semester} ${widget.albiruni.session}"),
actions: [
IconButton(
tooltip: "Prevous page",
onPressed: _page <= 1
? null
: () {
Expand All @@ -45,6 +46,7 @@ class _BrowserViewState extends State<BrowserView> {
icon: const Icon(Icons.navigate_before_outlined)),
Center(child: Text(_page.toString())),
IconButton(
tooltip: "Next page",
onPressed: () {
setState(() {
setState(() => _page++);
Expand Down
12 changes: 8 additions & 4 deletions lib/views/scheduler/course_validator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -61,7 +62,10 @@ class _CourseValidatorState extends State<CourseValidator>

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"),
),
Expand Down
2 changes: 1 addition & 1 deletion lib/views/scheduler/input_course.dart
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ class _InputCourseState extends State<InputCourse>
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,
Expand Down
Loading

0 comments on commit 3b85d96

Please sign in to comment.