Commit bf55755d authored by Administrator's avatar Administrator

autotagging on actvity level

parent 4ccfa219
{"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-05-22 08:38:48.502053","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-05-22 14:16:02.058685","version":"1.17.1"}
\ No newline at end of file
import 'package:encrateia/models/power_zone.dart';
import 'package:encrateia/models/strava_fit_download.dart';
import 'package:flutter/material.dart';
import 'package:encrateia/model/model.dart';
......@@ -7,6 +8,7 @@ import 'package:strava_flutter/Models/activity.dart' as StravaActivity;
import 'package:encrateia/models/athlete.dart';
import 'package:encrateia/models/event.dart';
import 'package:encrateia/models/lap.dart';
import 'package:encrateia/models/tag.dart';
import 'package:encrateia/models/power_zone_schema.dart';
import 'package:fit_parser/fit_parser.dart';
import 'package:path_provider/path_provider.dart';
......@@ -16,6 +18,8 @@ import 'package:intl/intl.dart';
import 'package:encrateia/utils/enums.dart';
import 'dart:io';
import 'activity_tagging.dart';
import 'heart_rate_zone.dart';
import 'heart_rate_zone_schema.dart';
class Activity extends ChangeNotifier {
......@@ -519,4 +523,68 @@ class Activity extends ChangeNotifier {
);
return heartRateZoneSchema;
}
getPowerZone() async {
var powerZoneSchema = await getPowerZoneSchema();
var dbPowerZone = await DbPowerZone()
.select()
.powerZoneSchemataId
.equals(powerZoneSchema.db.id)
.and
.lowerLimit
.lessThanOrEquals(db.avgPower)
.and
.upperLimit
.greaterThanOrEquals(db.avgPower)
.toSingle();
return PowerZone.fromDb(dbPowerZone);
}
getHeartRateZone() async {
var heartRateZoneSchema = await getHeartRateZoneSchema();
var dbHeartRateZone = await DbHeartRateZone()
.select()
.heartRateZoneSchemataId
.equals(heartRateZoneSchema.db.id)
.and
.lowerLimit
.lessThanOrEquals(db.avgHeartRate)
.and
.upperLimit
.greaterThanOrEquals(db.avgHeartRate)
.toSingle();
return HeartRateZone.fromDb(dbHeartRateZone);
}
autoTagger({Athlete athlete}) async {
PowerZone powerZone = await getPowerZone();
if (powerZone.db != null) {
Tag powerTag = await Tag.ensureAutoPowerTag(
athlete: athlete,
color: powerZone.db.color,
name: powerZone.db.name,
);
await ActivityTagging.createBy(
activity: this,
tag: powerTag,
system: true,
);
}
HeartRateZone heartRateZone = await getHeartRateZone();
if (heartRateZone.db != null) {
Tag heartRateTag = await Tag.ensureAutoHeartRateTag(
athlete: athlete,
color: heartRateZone.db.color,
name: heartRateZone.db.name,
);
await ActivityTagging.createBy(
activity: this,
tag: heartRateTag,
system: true,
);
}
}
}
......@@ -9,11 +9,12 @@ class ActivityTagging extends ChangeNotifier {
ActivityTagging({
@required Activity activity,
@required Tag tag,
bool system,
}) {
db = DbActivityTagging()
..activitiesId = activity.db.id
..tagsId = tag.db.id
..system = false;
..system = system ?? false;
}
ActivityTagging.fromDb(this.db);
......@@ -21,6 +22,7 @@ class ActivityTagging extends ChangeNotifier {
static createBy({
@required Activity activity,
@required Tag tag,
bool system,
}) async {
var dbActivityTagging = await DbActivityTagging()
.select()
......@@ -37,6 +39,7 @@ class ActivityTagging extends ChangeNotifier {
var activityTagging = ActivityTagging(
activity: activity,
tag: tag,
system: system ?? false
);
await activityTagging.db.save();
return activityTagging;
......
......@@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
import 'package:encrateia/model/model.dart';
import 'package:encrateia/models/tag_group.dart';
import 'athlete.dart';
class Tag extends ChangeNotifier {
DbTag db;
bool selected = false;
......@@ -29,4 +31,62 @@ class Tag extends ChangeNotifier {
var tags = dbTagList.map((dbTag) => Tag.fromDb(dbTag)).toList();
return tags;
}
static ensureAutoPowerTag({
@required Athlete athlete,
@required String name,
@required int color,
}) async {
DbTag dbPowerTag;
TagGroup autoPowerTagGroup =
await TagGroup.autoPowerTagGroup(athlete: athlete);
dbPowerTag = await DbTag()
.select()
.tagGroupsId
.equals(autoPowerTagGroup.db.id)
.and
.name
.equals(name)
.toSingle();
if (dbPowerTag == null) {
dbPowerTag = DbTag()
..tagGroupsId = autoPowerTagGroup.db.id
..color = color
..name = name
..system = true;
await dbPowerTag.save();
}
return Tag.fromDb(dbPowerTag);
}
static ensureAutoHeartRateTag({
@required Athlete athlete,
@required String name,
@required int color,
}) async {
DbTag dbHeartRateTag;
TagGroup autoHeartRateTagGroup =
await TagGroup.autoHeartRateTagGroup(athlete: athlete);
dbHeartRateTag = await DbTag()
.select()
.tagGroupsId
.equals(autoHeartRateTagGroup.db.id)
.and
.name
.equals(name)
.toSingle();
if (dbHeartRateTag == null) {
dbHeartRateTag = DbTag()
..tagGroupsId = autoHeartRateTagGroup.db.id
..color = color
..name = name
..system = true;
await dbHeartRateTag.save();
}
return Tag.fromDb(dbHeartRateTag);
}
}
......@@ -62,6 +62,36 @@ class TagGroup extends ChangeNotifier {
await autoPowerZonesTagGroup.db.save();
}
static autoPowerTagGroup({Athlete athlete}) async {
var dbTagGroup = await DbTagGroup()
.select()
.system
.equals(true)
.and
.athletesId
.equals(athlete.db.id)
.and
.name
.equals("Auto Power Zones")
.toSingle();
return TagGroup.fromDb(dbTagGroup);
}
static autoHeartRateTagGroup({Athlete athlete}) async {
var dbTagGroup = await DbTagGroup()
.select()
.system
.equals(true)
.and
.athletesId
.equals(athlete.db.id)
.and
.name
.equals("Auto Heart Rate Zones")
.toSingle();
return TagGroup.fromDb(dbTagGroup);
}
static includingActivityTaggings({
@required Athlete athlete,
@required Activity activity,
......@@ -91,14 +121,11 @@ class TagGroup extends ChangeNotifier {
}) async {
var tagGroups = await all(athlete: athlete);
var dbLapTaggings = await DbLapTagging()
.select()
.lapsId
.equals(lap.db.id)
.toList();
var dbLapTaggings =
await DbLapTagging().select().lapsId.equals(lap.db.id).toList();
var selectedTagIds = dbLapTaggings
.map((DbLapTagging dbLapTagging) => dbLapTagging.tagsId);
var selectedTagIds =
dbLapTaggings.map((DbLapTagging dbLapTagging) => dbLapTagging.tagsId);
for (TagGroup tagGroup in tagGroups) {
tagGroup.cachedTags = await tagGroup.tags;
......
......@@ -22,8 +22,9 @@ import 'package:flutter/material.dart';
import 'package:encrateia/models/activity.dart';
import 'package:encrateia/utils/icon_utils.dart';
import 'package:flutter/widgets.dart';
import 'package:flushbar/flushbar.dart';
class ShowActivityScreen extends StatelessWidget {
class ShowActivityScreen extends StatefulWidget {
final Activity activity;
final Athlete athlete;
......@@ -33,13 +34,20 @@ class ShowActivityScreen extends StatelessWidget {
@required this.athlete,
}) : super(key: key);
@override
_ShowActivityScreenState createState() => _ShowActivityScreenState();
}
class _ShowActivityScreenState extends State<ShowActivityScreen> {
Flushbar flushbar = Flushbar();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: MyColor.activity,
title: Text(
'${activity.db.name}',
'${widget.activity.db.name}',
overflow: TextOverflow.ellipsis,
),
),
......@@ -57,8 +65,8 @@ class ShowActivityScreen extends StatelessWidget {
icon: MyIcon.overView,
context: context,
nextWidget: ActivityOverviewWidget(
activity: activity,
athlete: athlete,
activity: widget.activity,
athlete: widget.athlete,
),
),
navigationButton(
......@@ -68,8 +76,8 @@ class ShowActivityScreen extends StatelessWidget {
icon: MyIcon.laps,
context: context,
nextWidget: LapsListWidget(
activity: activity,
athlete: athlete,
activity: widget.activity,
athlete: widget.athlete,
),
),
navigationButton(
......@@ -78,8 +86,8 @@ class ShowActivityScreen extends StatelessWidget {
icon: MyIcon.heartRate,
context: context,
nextWidget: ActivityHeartRateWidget(
activity: activity,
athlete: athlete,
activity: widget.activity,
athlete: widget.athlete,
),
),
navigationButton(
......@@ -88,8 +96,8 @@ class ShowActivityScreen extends StatelessWidget {
icon: MyIcon.power,
context: context,
nextWidget: ActivityPowerWidget(
activity: activity,
athlete: athlete,
activity: widget.activity,
athlete: widget.athlete,
),
),
navigationButton(
......@@ -98,8 +106,8 @@ class ShowActivityScreen extends StatelessWidget {
icon: MyIcon.powerDuration,
context: context,
nextWidget: ActivityPowerDurationWidget(
activity: activity,
athlete: athlete,
activity: widget.activity,
athlete: widget.athlete,
),
),
navigationButton(
......@@ -108,8 +116,8 @@ class ShowActivityScreen extends StatelessWidget {
icon: MyIcon.power,
context: context,
nextWidget: ActivityPowerPerHeartRateWidget(
activity: activity,
athlete: athlete,
activity: widget.activity,
athlete: widget.athlete,
),
),
navigationButton(
......@@ -118,8 +126,8 @@ class ShowActivityScreen extends StatelessWidget {
icon: MyIcon.power,
context: context,
nextWidget: ActivityEcorWidget(
activity: activity,
athlete: athlete,
activity: widget.activity,
athlete: widget.athlete,
),
),
navigationButton(
......@@ -128,8 +136,8 @@ class ShowActivityScreen extends StatelessWidget {
icon: MyIcon.speed,
context: context,
nextWidget: ActivitySpeedPerHeartRateWidget(
activity: activity,
athlete: athlete,
activity: widget.activity,
athlete: widget.athlete,
),
),
navigationButton(
......@@ -138,8 +146,8 @@ class ShowActivityScreen extends StatelessWidget {
icon: MyIcon.groundTime,
context: context,
nextWidget: ActivityGroundTimeWidget(
activity: activity,
athlete: athlete,
activity: widget.activity,
athlete: widget.athlete,
),
),
navigationButton(
......@@ -148,8 +156,8 @@ class ShowActivityScreen extends StatelessWidget {
icon: MyIcon.formPower,
context: context,
nextWidget: ActivityFormPowerWidget(
activity: activity,
athlete: athlete,
activity: widget.activity,
athlete: widget.athlete,
),
),
navigationButton(
......@@ -158,8 +166,8 @@ class ShowActivityScreen extends StatelessWidget {
icon: MyIcon.formPower,
context: context,
nextWidget: ActivityPowerRatioWidget(
activity: activity,
athlete: athlete,
activity: widget.activity,
athlete: widget.athlete,
),
),
navigationButton(
......@@ -168,8 +176,8 @@ class ShowActivityScreen extends StatelessWidget {
icon: MyIcon.verticalOscillation,
context: context,
nextWidget: ActivityVerticalOscillationWidget(
activity: activity,
athlete: athlete,
activity: widget.activity,
athlete: widget.athlete,
),
),
navigationButton(
......@@ -178,8 +186,8 @@ class ShowActivityScreen extends StatelessWidget {
icon: MyIcon.strideRatio,
context: context,
nextWidget: ActivityStrideRatioWidget(
activity: activity,
athlete: athlete,
activity: widget.activity,
athlete: widget.athlete,
),
),
navigationButton(
......@@ -188,8 +196,8 @@ class ShowActivityScreen extends StatelessWidget {
icon: MyIcon.cadence,
context: context,
nextWidget: ActivityStrydCadenceWidget(
activity: activity,
athlete: athlete,
activity: widget.activity,
athlete: widget.athlete,
),
),
navigationButton(
......@@ -198,8 +206,8 @@ class ShowActivityScreen extends StatelessWidget {
icon: MyIcon.legSpringStiffness,
context: context,
nextWidget: ActivityLegSpringStiffnessWidget(
activity: activity,
athlete: athlete,
activity: widget.activity,
athlete: widget.athlete,
),
),
navigationButton(
......@@ -208,8 +216,8 @@ class ShowActivityScreen extends StatelessWidget {
icon: MyIcon.metaData,
context: context,
nextWidget: ActivityMetadataWidget(
activity: activity,
athlete: athlete,
activity: widget.activity,
athlete: widget.athlete,
),
),
navigationButton(
......@@ -218,10 +226,17 @@ class ShowActivityScreen extends StatelessWidget {
icon: MyIcon.tag,
context: context,
nextWidget: ActivityTagWidget(
activity: activity,
athlete: athlete,
activity: widget.activity,
athlete: widget.athlete,
),
),
RaisedButton.icon(
color: MyColor.add,
icon: MyIcon.settings,
textColor: MyColor.textColor(backgroundColor: MyColor.add),
label: Text("Rerun\n Autotagging"),
onPressed: () => autoTagger(),
),
],
);
}),
......@@ -245,7 +260,7 @@ class ShowActivityScreen extends StatelessWidget {
context,
MaterialPageRoute(
builder: (context) => ShowActivityDetailScreen(
activity: activity,
activity: widget.activity,
widget: nextWidget,
title: title,
backgroundColor: backgroundColor,
......@@ -254,4 +269,22 @@ class ShowActivityScreen extends StatelessWidget {
),
);
}
autoTagger() async {
flushbar = Flushbar(
message: "Starting Autotagger",
duration: Duration(seconds: 10),
icon: MyIcon.stravaDownloadWhite,
)..show(context);
await widget.activity.autoTagger(athlete: widget.athlete);
flushbar.dismiss();
Flushbar(
message: "Autotagging finished",
duration: Duration(seconds: 2),
icon: MyIcon.finishedWhite,
)..show(context);
setState(() {});
}
}
......@@ -117,6 +117,7 @@ class _ShowAthleteScreenState extends State<ShowAthleteScreen> {
),
RaisedButton.icon(
color: MyColor.add,
textColor: MyColor.textColor(backgroundColor: MyColor.add),
icon: MyIcon.downloadLocal,
label: Text("Import .fit\nfrom Folder"),
onPressed: () => importLocal(),
......@@ -124,6 +125,7 @@ class _ShowAthleteScreenState extends State<ShowAthleteScreen> {
RaisedButton.icon(
color: MyColor.add,
icon: MyIcon.settings,
textColor: MyColor.textColor(backgroundColor: MyColor.add),
label: Text("Recalculate\nAverages"),
onPressed: () => recalculate(),
),
......
import 'package:encrateia/models/athlete.dart';
import 'package:encrateia/models/weight.dart';
import 'package:encrateia/utils/enums.dart';
import 'package:encrateia/utils/my_color.dart';
import 'package:flutter/material.dart';
import 'package:encrateia/utils/date_time_utils.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:intl/intl.dart';
import 'package:encrateia/models/activity.dart';
import 'package:encrateia/utils/icon_utils.dart';
class ActivityOverviewWidget extends StatefulWidget {
final Activity activity;
......
......@@ -52,12 +52,12 @@ class _ActivityTagWidgetState extends State<ActivityTagWidget> {
style: TextStyle(
color: MyColor.textColor(
selected: tag.selected,
backgroundColor: Color(tag.db.color),
backgroundColor: Color(tag.db.color ?? 99999),
),
),
),
avatar: CircleAvatar(
backgroundColor: Color(tag.db.color),
backgroundColor: Color(tag.db.color ?? 99999),
),
onSelected: (selected) {
setState(() {
......@@ -76,7 +76,7 @@ class _ActivityTagWidgetState extends State<ActivityTagWidget> {
});
},
selected: tag.selected,
selectedColor: Color(tag.db.color),
selectedColor: Color(tag.db.color ?? 99999),
backgroundColor: MyColor.white,
elevation: 3,
padding: EdgeInsets.all(10),
......
import 'package:encrateia/utils/my_color.dart';
import 'package:flutter/material.dart';
import 'package:encrateia/utils/date_time_utils.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:intl/intl.dart';
import 'package:encrateia/models/lap.dart';
import 'package:encrateia/utils/icon_utils.dart';
class LapMetadataWidget extends StatelessWidget {
final Lap lap;
......
import 'package:encrateia/utils/icon_utils.dart';
import 'package:encrateia/utils/my_color.dart';
import 'package:flutter/material.dart';
import 'package:encrateia/utils/date_time_utils.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
......
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