Commit 7bc6cc1d authored by Administrator's avatar Administrator

filter seems to be working

parent 7b53418f
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"flutter_secure_storage","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_secure_storage-3.3.3/","dependencies":[]},{"name":"path_provider","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.8/","dependencies":[]},{"name":"shared_preferences","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.7+2/","dependencies":[]},{"name":"sqflite","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/sqflite-1.3.0+1/","dependencies":[]},{"name":"uni_links","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/uni_links-0.4.0/","dependencies":[]},{"name":"url_launcher","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-5.4.7/","dependencies":[]}],"android":[{"name":"flutter_secure_storage","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_secure_storage-3.3.3/","dependencies":[]},{"name":"path_provider","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.8/","dependencies":[]},{"name":"shared_preferences","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.7+2/","dependencies":[]},{"name":"sqflite","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/sqflite-1.3.0+1/","dependencies":[]},{"name":"uni_links","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/uni_links-0.4.0/","dependencies":[]},{"name":"url_launcher","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-5.4.7/","dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.4+2/","dependencies":[]},{"name":"shared_preferences_macos","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences_macos-0.0.1+8/","dependencies":[]},{"name":"sqflite","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/sqflite-1.3.0+1/","dependencies":[]},{"name":"url_launcher_macos","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_macos-0.0.1+5/","dependencies":[]}],"linux":[],"windows":[],"web":[{"name":"shared_preferences_web","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences_web-0.1.2+5/","dependencies":[]},{"name":"url_launcher_web","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_web-0.1.1+5/","dependencies":[]}]},"dependencyGraph":[{"name":"flutter_secure_storage","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_macos"]},{"name":"path_provider_macos","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_macos","shared_preferences_web"]},{"name":"shared_preferences_macos","dependencies":[]},{"name":"shared_preferences_web","dependencies":[]},{"name":"sqflite","dependencies":[]},{"name":"uni_links","dependencies":[]},{"name":"url_launcher","dependencies":["url_launcher_web","url_launcher_macos"]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_web","dependencies":[]}],"date_created":"2020-06-02 10:59:56.615413","version":"1.17.1"}
\ No newline at end of file
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"flutter_secure_storage","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_secure_storage-3.3.3/","dependencies":[]},{"name":"path_provider","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.8/","dependencies":[]},{"name":"shared_preferences","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.7+2/","dependencies":[]},{"name":"sqflite","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/sqflite-1.3.0+1/","dependencies":[]},{"name":"uni_links","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/uni_links-0.4.0/","dependencies":[]},{"name":"url_launcher","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-5.4.7/","dependencies":[]}],"android":[{"name":"flutter_secure_storage","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_secure_storage-3.3.3/","dependencies":[]},{"name":"path_provider","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.8/","dependencies":[]},{"name":"shared_preferences","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.7+2/","dependencies":[]},{"name":"sqflite","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/sqflite-1.3.0+1/","dependencies":[]},{"name":"uni_links","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/uni_links-0.4.0/","dependencies":[]},{"name":"url_launcher","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-5.4.7/","dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.4+2/","dependencies":[]},{"name":"shared_preferences_macos","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences_macos-0.0.1+8/","dependencies":[]},{"name":"sqflite","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/sqflite-1.3.0+1/","dependencies":[]},{"name":"url_launcher_macos","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_macos-0.0.1+5/","dependencies":[]}],"linux":[],"windows":[],"web":[{"name":"shared_preferences_web","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences_web-0.1.2+5/","dependencies":[]},{"name":"url_launcher_web","path":"/home/stefan/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_web-0.1.1+5/","dependencies":[]}]},"dependencyGraph":[{"name":"flutter_secure_storage","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_macos"]},{"name":"path_provider_macos","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_macos","shared_preferences_web"]},{"name":"shared_preferences_macos","dependencies":[]},{"name":"shared_preferences_web","dependencies":[]},{"name":"sqflite","dependencies":[]},{"name":"uni_links","dependencies":[]},{"name":"url_launcher","dependencies":["url_launcher_web","url_launcher_macos"]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_web","dependencies":[]}],"date_created":"2020-06-02 17:57:41.184056","version":"1.17.1"}
\ No newline at end of file
import 'package:encrateia/models/activity.dart';
import 'package:encrateia/models/tag.dart';
import 'package:encrateia/models/tag_group.dart';
import 'package:encrateia/model/model.dart';
import 'package:flutter/material.dart';
import 'package:encrateia/utils/enums.dart';
import 'package:collection/collection.dart';
import 'athlete.dart';
class ActivityList<E> extends DelegatingList<E> {
ActivityList(List<E> activities)
......@@ -25,8 +29,9 @@ class ActivityList<E> extends DelegatingList<E> {
.difference(_activities[olderIndex].db.timeCreated)
.inHours /
24;
if (daysAgo > fullDecay)
if (daysAgo > fullDecay) {
break;
}
sumOfAvg += (fullDecay - daysAgo) *
(_activities[olderIndex].getAttribute(activityAttr) as num);
sumOfWeightings += fullDecay - daysAgo;
......@@ -35,4 +40,53 @@ class ActivityList<E> extends DelegatingList<E> {
activity.glidingMeasureAttribute = sumOfAvg / sumOfWeightings;
});
}
Future<ActivityList<Activity>> applyFilter({
Athlete athlete,
List<TagGroup> tagGroups,
}) async {
List<int> activityIds = <int>[];
List<int> tagIds = <int>[];
if (athlete.filters.isEmpty) {
return ActivityList<Activity>(_activities);
}
if (tagGroups != null && athlete.filters.isNotEmpty) {
// get active filters for TagGroup
for (final TagGroup tagGroup in tagGroups) {
tagIds = tagGroup.cachedTags.map((Tag tag) => tag.db.id).toList();
tagIds.removeWhere((int tagId) => !athlete.filters.contains(tagId));
// If there are restrictions for this group:
if (tagIds.isNotEmpty) {
// get ActivityTaggings ...
final List<DbActivityTagging> dbTaggings = await DbActivityTagging()
.select()
.tagsId
.inValues(tagIds)
.toList();
// ... and the Activity's ids
final List<int> activityIdsFromThisGroup = dbTaggings
.map((DbActivityTagging dbActivityTagging) =>
dbActivityTagging.activitiesId)
.toList();
// For the first result set ...
if (activityIds.isEmpty)
// use that result set.
activityIds = activityIdsFromThisGroup;
else
// For the others: intersect.
activityIds.removeWhere(
(int tagId) => !activityIdsFromThisGroup.contains(tagId));
}
}
}
final List<Activity> activityList = _activities
.where((Activity activity) => activityIds.contains(activity.db.id))
.toList();
return ActivityList<Activity>(activityList);
}
}
......@@ -19,6 +19,7 @@ class Athlete extends ChangeNotifier {
String firstName;
String lastName;
DbAthlete db = DbAthlete();
List<int> filters = <int> [];
@override
String toString() =>
......
import 'package:encrateia/models/athlete.dart';
import 'package:encrateia/models/tag.dart';
import 'package:encrateia/models/tag_group.dart';
import 'package:encrateia/utils/my_button.dart';
import 'package:encrateia/utils/my_color.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
class AddFilterScreen extends StatefulWidget {
const AddFilterScreen({
Key key,
this.athlete,
}) : super(key: key);
final Athlete athlete;
@override
_AddFilterScreenState createState() => _AddFilterScreenState();
}
class _AddFilterScreenState extends State<AddFilterScreen> {
List<TagGroup> tagGroups;
@override
void initState() {
getData();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: MyColor.settings,
title: const Text('Add Filter'),
),
body: Column(
children: <Widget>[
const Card(
child: ListTile(
title: Text('Filter Logic'),
subtitle:
Text('Tags within the same group are applied with an OR '
'operation, filters from different groups with an AND '
'operation.'),
),
),
StaggeredGridView.countBuilder(
shrinkWrap: true,
crossAxisCount:
MediaQuery.of(context).orientation == Orientation.portrait
? 2
: 3,
itemCount: tagGroups == null ? 0 : tagGroups.length,
itemBuilder: (BuildContext context, int index) => Card(
child: ListTile(
title: Text(tagGroups[index].db.name + '\n'),
subtitle: Wrap(
spacing: 15,
children: <Widget>[
for (Tag tag in tagGroups[index].cachedTags)
FilterChip(
label: Text(
tag.db.name,
style: TextStyle(
color: MyColor.textColor(
selected:
widget.athlete.filters.contains(tag.db.id),
backgroundColor: Color(tag.db.color ?? 99999),
),
),
),
avatar: CircleAvatar(
backgroundColor: Color(tag.db.color ?? 99999),
),
onSelected: (bool selected) {
setState(() {
if (selected)
widget.athlete.filters.add(tag.db.id);
else
widget.athlete.filters.removeWhere(
(int tagId) => tagId == tag.db.id);
});
},
selected: widget.athlete.filters.contains(tag.db.id),
selectedColor: Color(tag.db.color ?? 99999),
backgroundColor: MyColor.white,
elevation: 3,
padding: const EdgeInsets.all(10),
)
],
),
),
),
staggeredTileBuilder: (_) => const StaggeredTile.fit(1),
mainAxisSpacing: 3,
crossAxisSpacing: 3,
),
Row(mainAxisAlignment: MainAxisAlignment.end, children: <Widget>[
MyButton.save(
child: const Text('Save'),
onPressed: () {
Navigator.of(context).pop();
},
),
const SizedBox(width: 20),
]),
],
),
);
}
Future<void> getData() async {
tagGroups = await TagGroup.all(athlete: widget.athlete);
setState(() {});
}
}
import 'package:encrateia/models/athlete.dart';
import 'package:encrateia/models/tag.dart';
import 'package:encrateia/models/tag_group.dart';
import 'package:encrateia/utils/my_color.dart';
import 'package:flutter/material.dart';
class AthleteCurrentFilterWidget extends StatelessWidget {
const AthleteCurrentFilterWidget({
@required this.athlete,
@required this.tagGroups,
});
final Athlete athlete;
final List<TagGroup> tagGroups;
@override
Widget build(BuildContext context) {
bool empty;
if (tagGroups != null && athlete.filters.isNotEmpty) {
final List<Widget> widgets = <Widget>[];
widgets.add(const Text('Current Filter: '));
for (final TagGroup tagGroup in tagGroups) {
empty = true;
for (final Tag tag in tagGroup.cachedTags) {
if (athlete.filters.contains(tag.db.id)) {
if (empty == true) {
widgets.add(const Text('('));
widgets.add(Text(' ${tagGroup.db.name}: '));
empty = false;
} else
widgets.add(const Text('OR'));
widgets.add(
Chip(
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
padding: const EdgeInsets.fromLTRB(4, -6, 4, -6),
labelPadding: const EdgeInsets.fromLTRB(0, -6, 0, -6),
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(1))),
label: Text(
tag.db.name,
style: TextStyle(
color: MyColor.textColor(
selected: true,
backgroundColor: Color(tag.db.color ?? 99999),
),
),
),
backgroundColor: Color(tag.db.color ?? 99999),
elevation: 3,
),
);
}
}
if (empty == false) {
empty = true;
widgets.add(const Text(')'));
if (tagGroup != tagGroups.last)
widgets.add(const Text('AND'));
}
}
return Wrap(
spacing: 5,
runSpacing: 15,
children: widgets,
);
} else
return Container();
}
}
import 'package:encrateia/models/activity_list.dart';
import 'package:encrateia/models/tag_group.dart';
import 'package:encrateia/screens/add_filter_screen.dart';
import 'package:encrateia/utils/athlete_time_series_chart.dart';
import 'package:encrateia/utils/enums.dart';
import 'package:encrateia/utils/my_button.dart';
import 'package:flutter/material.dart';
import 'package:encrateia/models/athlete.dart';
import 'package:encrateia/models/activity.dart';
import 'athlete_current_filter_widget.dart';
class AthletePowerWidget extends StatefulWidget {
const AthletePowerWidget({this.athlete});
final Athlete athlete;
@override
_AthletePowerWidgetState createState() => _AthletePowerWidgetState();
}
class _AthletePowerWidgetState extends State<AthletePowerWidget> {
List<Activity> activities = <Activity>[];
ActivityList<Activity> activities = ActivityList<Activity>(<Activity>[]);
List<TagGroup> tagGroups = <TagGroup>[];
String loadingStatus = 'Loading ...';
@override
void initState() {
......@@ -35,13 +43,14 @@ class _AthletePowerWidgetState extends State<AthletePowerWidget> {
child: ListView(
padding: const EdgeInsets.only(left: 25),
children: <Widget>[
AthleteTimeSeriesChart(
activities: powerActivities,
chartTitleText: 'Power (W)',
activityAttr: ActivityAttr.avgPower,
athlete: widget.athlete,
),
],
AthleteTimeSeriesChart(
activities: powerActivities,
chartTitleText: 'Power (W)',
activityAttr: ActivityAttr.avgPower,
athlete: widget.athlete,
),
] +
filterWidgets(),
),
);
} else {
......@@ -50,15 +59,57 @@ class _AthletePowerWidgetState extends State<AthletePowerWidget> {
);
}
} else {
return const Center(
child: Text('Loading'),
);
return ListView(
children: <Widget>[
const SizedBox(height: 50,),
Center(
child: Text(loadingStatus),
),
const SizedBox(height: 50,),
] +
filterWidgets());
}
}
Future<void> getData() async {
final Athlete athlete = widget.athlete;
activities = await athlete.activities;
final List<Activity> unfilteredActivities = await athlete.activities;
tagGroups = await TagGroup.all(athlete: widget.athlete);
activities = await ActivityList<Activity>(unfilteredActivities).applyFilter(
athlete: widget.athlete,
tagGroups: tagGroups,
);
loadingStatus = activities.length.toString() + ' activities found';
setState(() {});
}
List<Widget> filterWidgets() {
return <Widget>[
const SizedBox(height: 40),
AthleteCurrentFilterWidget(
athlete: widget.athlete,
tagGroups: tagGroups,
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
MyButton.add(
child: const Text('Add filter'),
onPressed: () async {
await Navigator.push(
context,
MaterialPageRoute<BuildContext>(
builder: (BuildContext context) => AddFilterScreen(
athlete: widget.athlete,
),
),
);
getData();
},
),
const SizedBox(width: 20),
],
),
];
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment