Skip to content

Commit

Permalink
feat: can now add new activities
Browse files Browse the repository at this point in the history
  • Loading branch information
asartalo committed Jun 10, 2022
1 parent f669089 commit fb74130
Show file tree
Hide file tree
Showing 10 changed files with 185 additions and 33 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Aralan

Homeschool tools
Tools to keep track of daily homeschool activities.


55 changes: 55 additions & 0 deletions lib/elements/activity_dialog.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import 'package:flutter/material.dart';

import '../models/activity.dart';

class ActivityDialog extends StatefulWidget {
final Activity activity;
const ActivityDialog({Key? key, required this.activity}) : super(key: key);

static Future<Activity?> open(BuildContext context, Activity activity) {
return showDialog(
context: context,
builder: (context) => ActivityDialog(activity: activity),
);
}

@override
State<ActivityDialog> createState() => _ActivityDialogState();
}

class _ActivityDialogState extends State<ActivityDialog> {
late Activity activity;

@override
initState() {
super.initState();
activity = widget.activity;
}

@override
Widget build(BuildContext context) {
return AlertDialog(
title: const Text('Edit Activity'),
content: TextFormField(
autofocus: true,
decoration: const InputDecoration(hintText: 'Enter activity name'),
initialValue: activity.name,
onChanged: (str) {
setState(() {
activity = activity.update(name: str);
});
},
),
actions: [
TextButton(
onPressed: () => submit(context),
child: const Text('SAVE'),
),
],
);
}

void submit(BuildContext context) {
Navigator.of(context).pop<Activity?>(activity);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import 'package:flutter/material.dart';

import '../models/activity.dart';

class EditableActivity extends StatelessWidget {
class ActivityListTile extends StatelessWidget {
final Activity activity;

const EditableActivity({Key? key, required this.activity}) : super(key: key);
const ActivityListTile({Key? key, required this.activity}) : super(key: key);

@override
Widget build(BuildContext context) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import 'package:aralan/elements/toggle_activity.dart';
import 'package:aralan/tools/reorder.dart';
import 'package:flutter/material.dart';

import '../models/activity.dart';
import 'editable_activity.dart';
import 'activity_list_tile.dart';
import 'h3.dart';
import 'list_container.dart';

typedef OnChooseActivities = Function(List<Activity> activity);

class EditActivities extends StatefulWidget {
class ChooseAndOrderActivities extends StatefulWidget {
final List<Activity> list;
final OnChooseActivities onChoose;
final List<Activity> available;
final String? title;
const EditActivities({
const ChooseAndOrderActivities({
Key? key,
required this.list,
required this.onChoose,
Expand All @@ -22,10 +23,11 @@ class EditActivities extends StatefulWidget {
}) : super(key: key);

@override
State<EditActivities> createState() => _EditActivitiesState();
State<ChooseAndOrderActivities> createState() =>
_ChooseAndOrderActivitiesState();
}

class _EditActivitiesState extends State<EditActivities> {
class _ChooseAndOrderActivitiesState extends State<ChooseAndOrderActivities> {
Set<String> _selectedActivities = {};

@override
Expand Down Expand Up @@ -89,14 +91,12 @@ class _EditActivitiesState extends State<EditActivities> {
onReorder: (a, b) {
setState(() {
final tempList = _selectedActivities.toList();
final removed = tempList.removeAt(a);
tempList.insert(b, removed);
_selectedActivities = Set.from(tempList);
_selectedActivities = Set.from(reorder(tempList, a, b));
widget.onChoose(_chosenActivities());
});
},
builder: (activity, _) {
return EditableActivity(
return ActivityListTile(
key: Key(activity.id),
activity: activity,
);
Expand Down
40 changes: 40 additions & 0 deletions lib/elements/editable_activity_tile.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import 'package:aralan/elements/activity_dialog.dart';
import 'package:flutter/material.dart';

import '../models/activity.dart';

typedef OnChangeActivity = void Function(Activity activity);

class EditableActivityTile extends StatelessWidget {
final Activity activity;
final OnChangeActivity onChange;

const EditableActivityTile({
Key? key,
required this.activity,
required this.onChange,
}) : super(key: key);

@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return ListTile(
dense: true,
title: Text(
activity.name,
style: theme.textTheme.headline4?.copyWith(
fontWeight: FontWeight.normal,
),
),
leading: IconButton(
icon: const Icon(Icons.edit),
onPressed: () async {
final updated = await ActivityDialog.open(context, activity);
if (updated != null) {
onChange(updated);
}
},
),
);
}
}
4 changes: 4 additions & 0 deletions lib/models/activity.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ class Activity extends ActivityLike {
'name': name,
'id': id,
};

Activity update({required name}) {
return Activity(name: name, id: id);
}
}

class CheckableActivity extends ActivityLike {
Expand Down
5 changes: 5 additions & 0 deletions lib/models/activity_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ class ActivityRepository extends ChangeNotifier {
_updateStore();
}

update(Activity activity) {
_activitiesCache[activity.id] = activity;
_updateStore();
}

List<Activity> forWeekday(int weekday) {
final ids = _prefs.getStringList(_weekDayKey(weekday));
if (ids != null) {
Expand Down
62 changes: 41 additions & 21 deletions lib/settings_page.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:aralan/elements/edit_activities.dart';
import 'package:aralan/elements/editable_activity.dart';
import 'package:aralan/elements/activity_dialog.dart';
import 'package:aralan/elements/choose_and_order_activities.dart';
import 'package:aralan/elements/editable_activity_tile.dart';
import 'package:aralan/elements/navigation_button.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
Expand All @@ -21,6 +22,24 @@ class SettingsPage extends StatelessWidget {
final allActivities = repo.all();
final now = DateTime.now();

onChooseActivitiesToday(activities) {
repo.updateActivitiesToday(
ActivitiesToday.fromPlainActivities(
now,
activities,
),
);
}

onChooseDailyActivities(int weekday) {
return (activities) {
repo.updateForWeekday(
weekday,
activities,
);
};
}

return Scaffold(
body: SingleChildScrollView(
child: Stack(
Expand Down Expand Up @@ -49,42 +68,43 @@ class SettingsPage extends StatelessWidget {
ListContainer<Activity>(
list: allActivities,
builder: (activity, context) {
return EditableActivity(
activity: activity,
);
return EditableActivityTile(
activity: activity,
onChange: (activity) {
// debugPrint('Edited: ${activity.name}');
repo.update(activity);
});
},
),
TextButton(
onPressed: () async {
final newActivity = await ActivityDialog.open(
context, Activity(name: ''));
if (newActivity is Activity) {
repo.add(newActivity);
}
},
child: const Text('Add an Activity'),
),
],
),
),
Expanded(
child: Column(
children: [
const H2('Day Activities'),
EditActivities(
ChooseAndOrderActivities(
title: 'Activities Today',
list: repo.activitiesToday(now).plainActivities(),
onChoose: (activities) {
repo.updateActivitiesToday(
ActivitiesToday.fromPlainActivities(
now,
activities,
),
);
},
onChoose: onChooseActivitiesToday,
available: allActivities,
),
...(weekdays.keys.map((weekday) {
return EditActivities(
return ChooseAndOrderActivities(
title: weekdays[weekday].toString(),
list: repo.forWeekday(weekday),
available: allActivities,
onChoose: (activities) {
repo.updateForWeekday(
weekday,
activities,
);
},
onChoose: onChooseDailyActivities(weekday),
);
})),
],
Expand Down
5 changes: 5 additions & 0 deletions lib/tools/reorder.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
List<T> reorder<T>(List<T> list, int indexBefore, int indexAfter) {
final removed = list.removeAt(indexBefore);
list.insert(indexAfter, removed);
return list;
}
21 changes: 21 additions & 0 deletions test/tools/reorder_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import 'package:aralan/tools/reorder.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
group('reorder()', () {
test('It should move 2nd element to first', () {
final list = [1, 2, 3, 4];
expect(reorder(list, 1, 0), [2, 1, 3, 4]);
});

test('It should move 3rd element to last', () {
final list = [1, 2, 3, 4];
expect(reorder(list, 2, 3), [1, 2, 4, 3]);
});

test('It should move last element to first', () {
final list = [1, 2, 3, 4];
expect(reorder(list, 3, 0), [4, 1, 2, 3]);
});
});
}

0 comments on commit fb74130

Please sign in to comment.