Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
e2d321a
Update c2logbook.dart
pfredCL Mar 7, 2024
146463a
Merge pull request #1 from OpenRowingCommunity/main
pfredCL Mar 11, 2024
2f8c3b5
We need these
pfredCL Mar 11, 2024
76303b6
Biiiiig refactor
pfredCL Mar 11, 2024
13aa69e
Anotha one
pfredCL Mar 12, 2024
54e9bf8
Parsing support added for full c2 results
pfredCL Mar 12, 2024
3559304
Added rest time
pfredCL Mar 12, 2024
e31c402
Fixed some errors that occur on docker compose up in crewlab
pfredCL Mar 12, 2024
5c2b68f
Fixed some errors that occur on docker compose up in crewlab
pfredCL Mar 12, 2024
9da62a4
I swear I fixed this wtf
pfredCL Mar 12, 2024
6f0787b
More tweaking of models
pfredCL Mar 12, 2024
1594270
More tweaking of models
pfredCL Mar 12, 2024
f2ecf3c
More tweaking of models
pfredCL Mar 12, 2024
8177406
More tweaking of models
pfredCL Mar 12, 2024
4aa321c
Re-added json keys
pfredCL Mar 12, 2024
b9b4eba
More model alterations
pfredCL Mar 12, 2024
a26ca1a
Alright no more mr nice guy
pfredCL Mar 12, 2024
81f1731
Alright no more mr nice guy
pfredCL Mar 12, 2024
ea413e0
Alright no more mr nice guy
pfredCL Mar 12, 2024
9c93cb5
Alright no more mr nice guy
pfredCL Mar 12, 2024
6371c93
Alright no more mr nice guy
pfredCL Mar 12, 2024
a6a124a
Alright no more mr nice guy
pfredCL Mar 12, 2024
8c437a3
Alright no more mr nice guy
pfredCL Mar 12, 2024
847a587
Alright no more mr nice guy
pfredCL Mar 12, 2024
81820c0
Alright no more mr nice guy
pfredCL Mar 12, 2024
8acef32
Refactored and simplified file structure and added data models for in…
pfredCL Mar 18, 2024
6f4a94e
update versions
Aldaniee Apr 16, 2025
0216e4c
Revert "update versions"
Aldaniee Apr 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
targets:
$default:
builders:
json_serializable:
generate_for:
- "**/types/**.dart"
options:
explicit_to_json: true
freezed:
generate_for:
- "**/types/**.dart"
options:
maybe_when: false
maybe_map: false
50 changes: 41 additions & 9 deletions example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ packages:
path: ".."
relative: true
source: path
version: "0.0.2"
version: "0.0.5"
characters:
dependency: transitive
description:
Expand Down Expand Up @@ -122,6 +122,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.8.1"
leak_tracker:
dependency: transitive
description:
name: leak_tracker
sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa"
url: "https://pub.dev"
source: hosted
version: "10.0.0"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0
url: "https://pub.dev"
source: hosted
version: "2.0.1"
leak_tracker_testing:
dependency: transitive
description:
name: leak_tracker_testing
sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47
url: "https://pub.dev"
source: hosted
version: "2.0.1"
lints:
dependency: transitive
description:
Expand All @@ -134,26 +158,26 @@ packages:
dependency: transitive
description:
name: matcher
sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
url: "https://pub.dev"
source: hosted
version: "0.12.16"
version: "0.12.16+1"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
url: "https://pub.dev"
source: hosted
version: "0.5.0"
version: "0.8.0"
meta:
dependency: transitive
description:
name: meta
sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
url: "https://pub.dev"
source: hosted
version: "1.10.0"
version: "1.11.0"
nested:
dependency: transitive
description:
Expand All @@ -174,10 +198,10 @@ packages:
dependency: transitive
description:
name: path
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
url: "https://pub.dev"
source: hosted
version: "1.8.3"
version: "1.9.0"
provider:
dependency: "direct main"
description:
Expand Down Expand Up @@ -255,6 +279,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.4"
vm_service:
dependency: transitive
description:
name: vm_service
sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
url: "https://pub.dev"
source: hosted
version: "13.0.0"
web:
dependency: transitive
description:
Expand Down
5 changes: 1 addition & 4 deletions lib/c2logbook.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@
library;

export 'src/c2logbook_base.dart';
export 'src/types/c2_user.dart';
export 'src/types/c2_types.dart';
export 'src/types/c2_results.dart';
export 'src/types/c2_webhook_result.dart';
export 'src/types/index.dart';

// TODO: Export any libraries intended for clients of this package.
1 change: 1 addition & 0 deletions lib/src/c2logbook_base.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'dart:convert';
import 'types/index.dart';

import 'package:oauth2/oauth2.dart' as oauth2;
import 'package:http/http.dart' as http;
Expand Down
11 changes: 11 additions & 0 deletions lib/src/types/c2_detailed_result.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
part of 'index.dart';

class C2DetailedResult {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason this class exists as a separate thing from C2WebhookResult? it seems to borrow similar comments from that class and serve the same intended function.

Copy link
Contributor

@MoralCode MoralCode Jun 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the webhook almost gives you all the data you need (except the number of intervals) and making a separate REST call (which may not be fully propagated across C2's network - fun fact) to the c2logbook API to retrieve this extra data is where this comes from

/// Parse the data from incoming webhooks from the Concept2 API.
///
/// Currently this only supports webhook data representing new workouts that have been added
static C2FullResults? parse(Map<String, dynamic> jsonBody) {
final Map<String, dynamic> jsonBodyData = jsonBody["data"];
return C2FullResults.fromJson(jsonBodyData);
}
}
43 changes: 43 additions & 0 deletions lib/src/types/c2_full_results.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// ignore_for_file: invalid_annotation_target

part of 'index.dart';

@freezed
class C2FullResults with _$C2FullResults {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this class provide something separately from the C2Results class? or is it largely just a copy to make changes less destructive/easy to undo/allow more rapid iteration?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this have something to do with differences between the result data from the webhook vs a GET call?

//TODO: figure out how to get this into JSON as time_formatted
// String get timeFormatted => Duration(
// seconds: this.time.toInt(),
// milliseconds:
// (this.time.remainder(1) * Duration.millisecondsPerSecond).toInt())
// .toString();

C2FullResults._();

factory C2FullResults({
@JsonKey(name: 'id') @Default(0) int id,
@JsonKey(name: 'user_id') @Default(0) int userId,
@JsonKey(name: 'date') @TimestampConverter() required DateTime date,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I notice in all the refactoring the field name for this got renamed from endDate (which i find to be more specific description of its purpose). I assume it was changed back to try and get the json keys to work automatically, but figured id check if theres a reason this cant be changed back now that the @JsonKey annotation is back.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is ok to change but make crewlab a migration guide for name changes

@JsonKey(name: 'timezone') String? timezone,
@JsonKey(name: 'date_utc') @TimestampOrNullConverter() DateTime? dateUtc,
@JsonKey(name: 'distance') @Default(0) int distance,
@JsonKey(name: 'type') @Default(C2ResultType.rower) C2ResultType type,
@JsonKey(name: 'time') @DecimalIntConverter.tenths() required double time,
@JsonKey(name: 'workout_type') @Default(C2APIWorkoutType.JustRow)
C2APIWorkoutType workoutType,
@JsonKey(name: 'source') @Default("c2logbook dart") String source,
@JsonKey(name: 'weight_class') @Default(C2WeightClass.heavyweight)
C2WeightClass weightClass,
@JsonKey(name: 'verified') @Default(false) bool verified,
@JsonKey(name: 'ranked') @Default(false) bool ranked,
@JsonKey(name: 'comments') String? comments,
@JsonKey(name: 'privacy') @Default(C2PrivacyLevel.private) C2PrivacyLevel privacy,
@JsonKey(name: 'rest_time') @DecimalIntConverter.tenths() double? restTime,
@JsonKey(name: 'stroke_rate') int? strokeRate,
@JsonKey(name: 'heart_rate') @Default(null) C2HeartRate? heartRate,
@JsonKey(name: 'workout') @Default(null) C2Workout? workout,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

was there an issue with the json keys for fields that dont have multiword names (like workout) where they werent getting recognized without making it explicit? or were these just added back for code cleanliness/formatting consistency?

I noticed when testing that if the key and the field name are the same, the @JsonKey isnt necessary to make explicit

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some fields werent making it in. adding them all fixed it

@JsonKey(name: 'rest_distance') @Default(0.0) double restDistance,
}) = _C2FullResults;

factory C2FullResults.fromJson(Map<dynamic, dynamic> json) =>
_$C2FullResultsFromJson(Map<String, dynamic>.from(json));
}
19 changes: 19 additions & 0 deletions lib/src/types/c2_heart_rate.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// ignore_for_file: invalid_annotation_target

part of 'index.dart';

@freezed
class C2HeartRate with _$C2HeartRate {

C2HeartRate._();

factory C2HeartRate({
@JsonKey(name: 'min') @Default(0) int min,
@JsonKey(name: 'average') @Default(0) int average,
@JsonKey(name: 'max') @Default(0) int max,
@JsonKey(name: 'ending') @Default(0) int ending,
}) = _C2HeartRate;

factory C2HeartRate.fromJson(Map<dynamic, dynamic> json) =>
_$C2HeartRateFromJson(Map<String, dynamic>.from(json));
}
22 changes: 22 additions & 0 deletions lib/src/types/c2_intervals.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// ignore_for_file: invalid_annotation_target

part of 'index.dart';

@freezed
class C2Intervals with _$C2Intervals {

C2Intervals._();

factory C2Intervals({
@JsonKey(name: 'id') @Default("type") String? type,
@JsonKey(name: 'time') @DecimalIntConverter.tenths() required double time,
@JsonKey(name: 'rest_time') @DecimalIntConverter.tenths() required double restTime,
@JsonKey(name: 'distance') @Default(0.0) double distance,
@JsonKey(name: 'calories_total') @Default(0) int caloriesTotal,
@JsonKey(name: 'stroke_rate') @Default(0) int strokeRate,
@JsonKey(name: 'heart_rate') @Default(null) C2HeartRate? heartRate,
}) = _C2Intervals;

factory C2Intervals.fromJson(Map<dynamic, dynamic> json) =>
_$C2IntervalsFromJson(Map<String, dynamic>.from(json));
}
44 changes: 18 additions & 26 deletions lib/src/types/c2_results.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
// ignore_for_file: invalid_annotation_target

import 'c2_types.dart';
import 'package:freezed_annotation/freezed_annotation.dart';

import '../utils.dart';

part 'c2_results.freezed.dart';
part 'c2_results.g.dart';
part of 'index.dart';

@freezed
class C2Results with _$C2Results {
Expand All @@ -20,28 +14,26 @@ class C2Results with _$C2Results {
C2Results._();

factory C2Results({
@Default(0) int id,
@JsonKey(name: "user_id") @Default(0) int userId,
@JsonKey(name: "date") @TimestampConverter() required DateTime endDate,
@JsonKey(name: "date_utc") @TimestampOrNullConverter() DateTime? dateUtc,
String? timezone,
@Default(0) int distance,
@Default(C2ResultType.rower) C2ResultType type,
@DecimalIntConverter.tenths() required double time,
@JsonKey(name: "workout_type")
@Default(C2APIWorkoutType.JustRow)
@JsonKey(name: 'id') @Default(0) int id,
@JsonKey(name: 'user_id') @Default(0) int userId,
@JsonKey(name: 'date') @TimestampConverter() required DateTime date,
@JsonKey(name: 'date_utc') @TimestampOrNullConverter() DateTime? dateUtc,
@JsonKey(name: 'timezone') String? timezone,
@JsonKey(name: 'distance') @Default(0) int distance,
@JsonKey(name: 'type') @Default(C2ResultType.rower) C2ResultType type,
@JsonKey(name: 'time') @DecimalIntConverter.tenths() required double time,
@JsonKey(name: 'workout_type') @Default(C2APIWorkoutType.JustRow)
C2APIWorkoutType workoutType,
@Default("c2logbook dart") String source,
@JsonKey(name: "weight_class")
@Default(C2WeightClass.heavyweight)
@JsonKey(name: 'source') @Default("c2logbook dart") String source,
@JsonKey(name: 'weight_class') @Default(C2WeightClass.heavyweight)
C2WeightClass weightClass,
@JsonKey(name: "stroke_rate") int? strokeRate,
@Default(false) bool verified,
@Default(false) bool ranked,
String? comments,
@Default(C2PrivacyLevel.private) C2PrivacyLevel privacy,
@JsonKey(name: 'stroke_rate') @Default(null) int? strokeRate,
@JsonKey(name: 'verified') @Default(false) bool verified,
@JsonKey(name: 'ranked') @Default(false) bool ranked,
@JsonKey(name: 'comments') @Default(null) String? comments,
@JsonKey(name: 'privacy') @Default(C2PrivacyLevel.private) C2PrivacyLevel privacy,
}) = _C2Results;

factory C2Results.fromJson(Map<dynamic, dynamic> json) =>
_$C2ResultsFromJson(Map<String, dynamic>.from(json));
}
}
Loading