diff --git a/fcm/lib/converter/device_client_id_nullable_converter.dart b/fcm/lib/converter/device_client_id_nullable_converter.dart new file mode 100644 index 000000000..2853d6ea3 --- /dev/null +++ b/fcm/lib/converter/device_client_id_nullable_converter.dart @@ -0,0 +1,12 @@ +import 'package:fcm/model/device_client_id.dart'; +import 'package:json_annotation/json_annotation.dart'; + +class DeviceClientIdNullableConverter implements JsonConverter { + const DeviceClientIdNullableConverter(); + + @override + DeviceClientId? fromJson(String? json) => json != null ? DeviceClientId(json) : null; + + @override + String? toJson(DeviceClientId? object) => object?.value; +} diff --git a/fcm/lib/converter/firebase_expired_time_nullable_converter.dart b/fcm/lib/converter/firebase_expired_time_nullable_converter.dart new file mode 100644 index 000000000..db1d076a0 --- /dev/null +++ b/fcm/lib/converter/firebase_expired_time_nullable_converter.dart @@ -0,0 +1,20 @@ +import 'package:fcm/model/firebase_expired_time.dart'; +import 'package:jmap_dart_client/http/converter/utc_date_converter.dart'; +import 'package:jmap_dart_client/http/converter/utc_date_nullable_converter.dart'; +import 'package:json_annotation/json_annotation.dart'; + +class FirebaseExpiredTimeNullableConverter implements JsonConverter { + const FirebaseExpiredTimeNullableConverter(); + + @override + FirebaseExpiredTime? fromJson(String? json) { + if (json != null) { + return FirebaseExpiredTime(const UTCDateConverter().fromJson(json)); + } else { + return null; + } + } + + @override + String? toJson(FirebaseExpiredTime? object) => const UTCDateNullableConverter().toJson(object?.value); +} \ No newline at end of file diff --git a/fcm/lib/converter/firebase_registration_id_nullable_converter.dart b/fcm/lib/converter/firebase_registration_id_nullable_converter.dart new file mode 100644 index 000000000..07b5b3ffc --- /dev/null +++ b/fcm/lib/converter/firebase_registration_id_nullable_converter.dart @@ -0,0 +1,13 @@ +import 'package:fcm/model/firebase_registration_id.dart'; +import 'package:jmap_dart_client/jmap/core/id.dart'; +import 'package:json_annotation/json_annotation.dart'; + +class FirebaseRegistrationIdNullableConverter implements JsonConverter { + const FirebaseRegistrationIdNullableConverter(); + + @override + FirebaseRegistrationId? fromJson(String? json) => json != null ? FirebaseRegistrationId(Id(json)) : null; + + @override + String? toJson(FirebaseRegistrationId? object) => object?.id.value; +} diff --git a/fcm/lib/converter/firebase_token_nullable_converter.dart b/fcm/lib/converter/firebase_token_nullable_converter.dart new file mode 100644 index 000000000..62b66aac0 --- /dev/null +++ b/fcm/lib/converter/firebase_token_nullable_converter.dart @@ -0,0 +1,12 @@ +import 'package:fcm/model/firebase_token.dart'; +import 'package:json_annotation/json_annotation.dart'; + +class FirebaseTokenNullableConverter implements JsonConverter { + const FirebaseTokenNullableConverter(); + + @override + FirebaseToken? fromJson(String? json) => json != null ? FirebaseToken(json) : null; + + @override + String? toJson(FirebaseToken? object) => object?.value; +} diff --git a/fcm/lib/converter/type_name_converter.dart b/fcm/lib/converter/type_name_converter.dart new file mode 100644 index 000000000..476084183 --- /dev/null +++ b/fcm/lib/converter/type_name_converter.dart @@ -0,0 +1,12 @@ +import 'package:fcm/model/type_name.dart'; +import 'package:json_annotation/json_annotation.dart'; + +class TypeNameConverter implements JsonConverter { + const TypeNameConverter(); + + @override + TypeName fromJson(String json) => TypeName(json); + + @override + String toJson(TypeName object) => object.value; +} diff --git a/fcm/lib/model/device_client_id.dart b/fcm/lib/model/device_client_id.dart new file mode 100644 index 000000000..47ac90550 --- /dev/null +++ b/fcm/lib/model/device_client_id.dart @@ -0,0 +1,12 @@ + +import 'package:equatable/equatable.dart'; + +class DeviceClientId with EquatableMixin { + + final String value; + + DeviceClientId(this.value); + + @override + List get props => [value]; +} \ No newline at end of file diff --git a/fcm/lib/model/firebase_expired_time.dart b/fcm/lib/model/firebase_expired_time.dart new file mode 100644 index 000000000..c0cc619dc --- /dev/null +++ b/fcm/lib/model/firebase_expired_time.dart @@ -0,0 +1,13 @@ + +import 'package:equatable/equatable.dart'; +import 'package:jmap_dart_client/jmap/core/utc_date.dart'; + +class FirebaseExpiredTime with EquatableMixin { + + final UTCDate value; + + FirebaseExpiredTime(this.value); + + @override + List get props => [value]; +} \ No newline at end of file diff --git a/fcm/lib/model/firebase_registration.dart b/fcm/lib/model/firebase_registration.dart new file mode 100644 index 000000000..d01a3ea35 --- /dev/null +++ b/fcm/lib/model/firebase_registration.dart @@ -0,0 +1,45 @@ + +import 'package:equatable/equatable.dart'; +import 'package:fcm/converter/device_client_id_nullable_converter.dart'; +import 'package:fcm/converter/firebase_expired_time_nullable_converter.dart'; +import 'package:fcm/converter/firebase_registration_id_nullable_converter.dart'; +import 'package:fcm/converter/firebase_token_nullable_converter.dart'; +import 'package:fcm/converter/type_name_converter.dart'; +import 'package:fcm/model/device_client_id.dart'; +import 'package:fcm/model/firebase_expired_time.dart'; +import 'package:fcm/model/firebase_registration_id.dart'; +import 'package:fcm/model/firebase_token.dart'; +import 'package:fcm/model/type_name.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'firebase_registration.g.dart'; + +@DeviceClientIdNullableConverter() +@FirebaseRegistrationIdNullableConverter() +@FirebaseTokenNullableConverter() +@FirebaseExpiredTimeNullableConverter() +@TypeNameConverter() +@JsonSerializable(explicitToJson: true, includeIfNull: false) +class FirebaseRegistration with EquatableMixin { + + final FirebaseRegistrationId? id; + final FirebaseToken? token; + final DeviceClientId? deviceClientId; + final FirebaseExpiredTime? expires; + final List? types; + + FirebaseRegistration({ + this.id, + this.token, + this.deviceClientId, + this.expires, + this.types + }); + + factory FirebaseRegistration.fromJson(Map json) => _$FirebaseRegistrationFromJson(json); + + Map toJson() => _$FirebaseRegistrationToJson(this); + + @override + List get props => [id, token, deviceClientId, expires, types]; +} \ No newline at end of file diff --git a/fcm/lib/model/firebase_registration_id.dart b/fcm/lib/model/firebase_registration_id.dart new file mode 100644 index 000000000..2f06b6784 --- /dev/null +++ b/fcm/lib/model/firebase_registration_id.dart @@ -0,0 +1,13 @@ + +import 'package:equatable/equatable.dart'; +import 'package:jmap_dart_client/jmap/core/id.dart'; + +class FirebaseRegistrationId with EquatableMixin { + + final Id id; + + FirebaseRegistrationId(this.id); + + @override + List get props => [id]; +} \ No newline at end of file diff --git a/fcm/lib/model/firebase_token.dart b/fcm/lib/model/firebase_token.dart new file mode 100644 index 000000000..c6e82567b --- /dev/null +++ b/fcm/lib/model/firebase_token.dart @@ -0,0 +1,12 @@ + +import 'package:equatable/equatable.dart'; + +class FirebaseToken with EquatableMixin { + + final String value; + + FirebaseToken(this.value); + + @override + List get props => [value]; +} \ No newline at end of file diff --git a/fcm/lib/model/type_name.dart b/fcm/lib/model/type_name.dart new file mode 100644 index 000000000..fe752a71c --- /dev/null +++ b/fcm/lib/model/type_name.dart @@ -0,0 +1,12 @@ + +import 'package:equatable/equatable.dart'; + +class TypeName with EquatableMixin { + + final String value; + + TypeName(this.value); + + @override + List get props => [value]; +} \ No newline at end of file diff --git a/fcm/lib/utils/fcm_utils.dart b/fcm/lib/utils/fcm_utils.dart new file mode 100644 index 000000000..e9dae5fb9 --- /dev/null +++ b/fcm/lib/utils/fcm_utils.dart @@ -0,0 +1,6 @@ + +import 'package:jmap_dart_client/jmap/core/capability/capability_identifier.dart'; + +class FCMUtils { + static final capabilityFCM = CapabilityIdentifier(Uri.parse('com:linagora:params:jmap:firebase:push')); +} \ No newline at end of file diff --git a/fcm/pubspec.lock b/fcm/pubspec.lock index 8a19e7393..d97b2c75f 100644 --- a/fcm/pubspec.lock +++ b/fcm/pubspec.lock @@ -1,6 +1,27 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + url: "https://pub.dartlang.org" + source: hosted + version: "47.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + url: "https://pub.dartlang.org" + source: hosted + version: "4.7.0" + args: + dependency: transitive + description: + name: args + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.1" async: dependency: transitive description: @@ -15,6 +36,62 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0" + build: + dependency: transitive + description: + name: build + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.1" + build_config: + dependency: transitive + description: + name: build_config + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + build_daemon: + dependency: transitive + description: + name: build_daemon + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" + build_resolvers: + dependency: transitive + description: + name: build_resolvers + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.10" + build_runner: + dependency: "direct dev" + description: + name: build_runner + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.11" + build_runner_core: + dependency: transitive + description: + name: build_runner_core + url: "https://pub.dartlang.org" + source: hosted + version: "7.2.7" + built_collection: + dependency: transitive + description: + name: built_collection + url: "https://pub.dartlang.org" + source: hosted + version: "5.1.1" + built_value: + dependency: transitive + description: + name: built_value + url: "https://pub.dartlang.org" + source: hosted + version: "8.4.2" characters: dependency: transitive description: @@ -29,6 +106,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.3.1" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" clock: dependency: transitive description: @@ -36,6 +120,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.0" + code_builder: + dependency: transitive + description: + name: code_builder + url: "https://pub.dartlang.org" + source: hosted + version: "4.3.0" collection: dependency: transitive description: @@ -43,6 +134,48 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.16.0" + convert: + dependency: transitive + description: + name: convert + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.2" + dart_style: + dependency: transitive + description: + name: dart_style + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.4" + dartz: + dependency: transitive + description: + name: dartz + url: "https://pub.dartlang.org" + source: hosted + version: "0.10.1" + dio: + dependency: transitive + description: + name: dio + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.6" + equatable: + dependency: "direct main" + description: + name: equatable + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3" fake_async: dependency: transitive description: @@ -50,16 +183,123 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.3.0" + file: + dependency: transitive + description: + name: file + url: "https://pub.dartlang.org" + source: hosted + version: "6.1.4" + fixnum: + dependency: transitive + description: + name: fixnum + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" flutter: dependency: "direct main" description: flutter source: sdk version: "0.0.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" flutter_test: dependency: "direct dev" description: flutter source: sdk version: "0.0.0" + frontend_server_client: + dependency: transitive + description: + name: frontend_server_client + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.3" + glob: + dependency: transitive + description: + name: glob + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.1" + graphs: + dependency: transitive + description: + name: graphs + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.0" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + url: "https://pub.dartlang.org" + source: hosted + version: "3.2.1" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.0" + io: + dependency: transitive + description: + name: io + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" + jmap_dart_client: + dependency: "direct main" + description: + path: "." + ref: master + resolved-ref: "66ef334ac2cf4d5cb30835b30094a51802fae2ba" + url: "https://github.com/linagora/jmap-dart-client.git" + source: git + version: "0.0.1" + js: + dependency: transitive + description: + name: js + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.5" + json_annotation: + dependency: "direct main" + description: + name: json_annotation + url: "https://pub.dartlang.org" + source: hosted + version: "4.5.0" + json_serializable: + dependency: "direct dev" + description: + name: json_serializable + url: "https://pub.dartlang.org" + source: hosted + version: "6.2.0" + lints: + dependency: transitive + description: + name: lints + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" + logging: + dependency: transitive + description: + name: logging + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" matcher: dependency: transitive description: @@ -81,6 +321,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.7.0" + mime: + dependency: transitive + description: + name: mime + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" + package_config: + dependency: transitive + description: + name: package_config + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" path: dependency: transitive description: @@ -88,11 +342,67 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.8.1" + pool: + dependency: transitive + description: + name: pool + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.1" + pub_semver: + dependency: transitive + description: + name: pub_semver + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.3" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1+1" + shelf: + dependency: transitive + description: + name: shelf + url: "https://pub.dartlang.org" + source: hosted + version: "1.4.0" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" sky_engine: dependency: transitive description: flutter source: sdk version: "0.0.99" + source_gen: + dependency: transitive + description: + name: source_gen + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.6" + source_helper: + dependency: transitive + description: + name: source_helper + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.3" source_span: dependency: transitive description: @@ -114,6 +424,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0" + stream_transform: + dependency: transitive + description: + name: stream_transform + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" string_scanner: dependency: transitive description: @@ -135,6 +452,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.4.9" + timing: + dependency: transitive + description: + name: timing + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.1" vector_math: dependency: transitive description: @@ -142,5 +473,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.2" + watcher: + dependency: transitive + description: + name: watcher + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.0" + yaml: + dependency: transitive + description: + name: yaml + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.1" sdks: dart: ">=2.17.0 <3.0.0" + flutter: ">=2.5.0" diff --git a/fcm/pubspec.yaml b/fcm/pubspec.yaml index 9c1ce8047..13eb6fbaa 100644 --- a/fcm/pubspec.yaml +++ b/fcm/pubspec.yaml @@ -11,9 +11,25 @@ dependencies: flutter: sdk: flutter + equatable: 2.0.3 + + json_annotation: 4.5.0 + + jmap_dart_client: + git: + url: https://github.com/linagora/jmap-dart-client.git + ref: master + dev_dependencies: flutter_test: sdk: flutter + flutter_lints: 1.0.4 + + build_runner: 2.1.11 + + json_serializable: 6.2.0 + flutter: + uses-material-design: true \ No newline at end of file