feat(do-not-disturb): add DND schedule feature with capabilities-driven UI
This commit is contained in:
@@ -190,6 +190,11 @@ void configureAppRouter() {
|
||||
name: 'volume_control',
|
||||
pageBuilder: const VolumeControlBuilder().buildPage,
|
||||
),
|
||||
GoRoute(
|
||||
path: 'do_not_disturb',
|
||||
name: 'do_not_disturb',
|
||||
pageBuilder: const DoNotDisturbBuilder().buildPage,
|
||||
),
|
||||
GoRoute(
|
||||
path: 'call_history',
|
||||
name: 'call_history',
|
||||
|
||||
@@ -9,5 +9,6 @@ export 'src/features/rewards/rewards_builder.dart';
|
||||
export 'src/features/activity_meter/activity_meter_builder.dart';
|
||||
export 'src/features/apps_use/apps_use_builder.dart';
|
||||
export 'src/features/volume_control/volume_control_builder.dart';
|
||||
export 'src/features/do_not_disturb/do_not_disturb_builder.dart';
|
||||
export 'src/features/call_history/call_history_builder.dart';
|
||||
export 'src/features/background_image/background_image_builder.dart';
|
||||
|
||||
@@ -15,6 +15,11 @@ class DeviceManagementScreen extends ConsumerWidget {
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final theme = ref.watch(themePortProvider);
|
||||
final capabilities = ref.watch(
|
||||
selectedDeviceProvider.select((device) => device.value?.capabilities),
|
||||
);
|
||||
final primaryColor = theme.getColorFor(ThemeCode.legacyPrimary);
|
||||
final gap = SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15));
|
||||
|
||||
return LegacyPageLayout(
|
||||
theme: theme,
|
||||
@@ -27,83 +32,93 @@ class DeviceManagementScreen extends ConsumerWidget {
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
if (capabilities?.commands?.enabled ?? false) ...[
|
||||
AppMenuButton(
|
||||
color: primaryColor,
|
||||
onPressed: () =>
|
||||
navigationContract.pushTo(AppRoutes.remoteConnection),
|
||||
icon: SFIcons.connection,
|
||||
text: context.translate(I18n.remoteConnection),
|
||||
),
|
||||
gap,
|
||||
],
|
||||
AppMenuButton(
|
||||
color: theme.getColorFor(ThemeCode.legacyPrimary),
|
||||
onPressed: () =>
|
||||
navigationContract.pushTo(AppRoutes.remoteConnection),
|
||||
icon: SFIcons.connection,
|
||||
text: context.translate(I18n.remoteConnection),
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
AppMenuButton(
|
||||
color: theme.getColorFor(ThemeCode.legacyPrimary),
|
||||
color: primaryColor,
|
||||
onPressed: () =>
|
||||
navigationContract.pushTo(AppRoutes.scheduledActivities),
|
||||
icon: SFIcons.calendarCircle,
|
||||
negativeIcon: true,
|
||||
text: context.translate(I18n.activityScheduleTitle),
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
if (capabilities?.contacts?.enabled ?? false) ...[
|
||||
gap,
|
||||
AppMenuButton(
|
||||
color: primaryColor,
|
||||
onPressed: () =>
|
||||
navigationContract.pushTo(AppRoutes.contacts),
|
||||
icon: SFIcons.contactsCircle,
|
||||
negativeIcon: true,
|
||||
text: context.translate(I18n.contactsAgendaTitle),
|
||||
),
|
||||
],
|
||||
if (capabilities?.doNotDisturbs != null) ...[
|
||||
gap,
|
||||
AppMenuButton(
|
||||
color: primaryColor,
|
||||
onPressed: () =>
|
||||
navigationContract.pushTo(AppRoutes.doNotDisturb),
|
||||
icon: SFIcons.doNotDisturbCircle,
|
||||
negativeIcon: true,
|
||||
text: context.translate(I18n.doNotDisturb),
|
||||
),
|
||||
],
|
||||
if (capabilities?.settings != null &&
|
||||
capabilities!.settings!.soundModes.isNotEmpty) ...[
|
||||
gap,
|
||||
AppMenuButton(
|
||||
color: primaryColor,
|
||||
onPressed: () =>
|
||||
navigationContract.pushTo(AppRoutes.volumeControl),
|
||||
icon: Icons.volume_up_outlined,
|
||||
iconSize: SizeUtils.getByScreen(small: 42, big: 40),
|
||||
text: context.translate(I18n.volumeControl),
|
||||
),
|
||||
],
|
||||
if ((capabilities?.heartbeats?.enabled ?? false) ||
|
||||
(capabilities?.bloodPressure?.enabled ?? false)) ...[
|
||||
gap,
|
||||
AppMenuButton(
|
||||
color: primaryColor,
|
||||
onPressed: () =>
|
||||
navigationContract.pushTo(AppRoutes.health),
|
||||
icon: SFIcons.healthCircle,
|
||||
negativeIcon: true,
|
||||
text: context.translate(I18n.healthTitle),
|
||||
),
|
||||
],
|
||||
if (capabilities?.podometer?.enabled ?? false) ...[
|
||||
gap,
|
||||
AppMenuButton(
|
||||
color: primaryColor,
|
||||
onPressed: () =>
|
||||
navigationContract.pushTo(AppRoutes.activityMeter),
|
||||
icon: SFIcons.healthCircle,
|
||||
negativeIcon: true,
|
||||
text: context.translate(I18n.activityMeter),
|
||||
),
|
||||
],
|
||||
gap,
|
||||
AppMenuButton(
|
||||
color: theme.getColorFor(ThemeCode.legacyPrimary),
|
||||
onPressed: () => navigationContract.pushTo(AppRoutes.contacts),
|
||||
icon: SFIcons.contactsCircle,
|
||||
negativeIcon: true,
|
||||
text: context.translate(I18n.contactsAgendaTitle),
|
||||
),
|
||||
// SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
// AppMenuButton(
|
||||
// color: theme.getColorFor(ThemeCode.legacyPrimary),
|
||||
// onPressed: () {},
|
||||
// icon: SFIcons.doNotDisturbCircle,
|
||||
// negativeIcon: true,
|
||||
// text: context.translate(I18n.doNotDisturb),
|
||||
// ),
|
||||
// SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
// AppMenuButton(
|
||||
// color: theme.getColorFor(ThemeCode.legacyPrimary),
|
||||
// onPressed: () {},
|
||||
// icon: SFIcons.videoCallCircle,
|
||||
// negativeIcon: true,
|
||||
// text: context.translate(I18n.videoCall),
|
||||
// ),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
AppMenuButton(
|
||||
color: theme.getColorFor(ThemeCode.legacyPrimary),
|
||||
color: primaryColor,
|
||||
onPressed: () =>
|
||||
navigationContract.pushTo(AppRoutes.volumeControl),
|
||||
icon: Icons.volume_up_outlined,
|
||||
iconSize: SizeUtils.getByScreen(small: 42, big: 40),
|
||||
text: context.translate(I18n.volumeControl),
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
AppMenuButton(
|
||||
color: theme.getColorFor(ThemeCode.legacyPrimary),
|
||||
onPressed: () => navigationContract.pushTo(AppRoutes.health),
|
||||
icon: SFIcons.healthCircle,
|
||||
negativeIcon: true,
|
||||
text: context.translate(I18n.healthTitle),
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
AppMenuButton(
|
||||
color: theme.getColorFor(ThemeCode.legacyPrimary),
|
||||
onPressed: () =>
|
||||
navigationContract.pushTo(AppRoutes.activityMeter),
|
||||
icon: SFIcons.healthCircle,
|
||||
negativeIcon: true,
|
||||
text: context.translate(I18n.activityMeter),
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
AppMenuButton(
|
||||
color: theme.getColorFor(ThemeCode.legacyPrimary),
|
||||
onPressed: () => navigationContract.pushTo(AppRoutes.rewards),
|
||||
navigationContract.pushTo(AppRoutes.rewards),
|
||||
icon: SFIcons.rewardsCircle,
|
||||
negativeIcon: true,
|
||||
text: context.translate(I18n.rewards),
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
gap,
|
||||
AppMenuButton(
|
||||
color: theme.getColorFor(ThemeCode.legacyPrimary),
|
||||
color: primaryColor,
|
||||
onPressed: () => showDialog(
|
||||
context: context,
|
||||
builder: (_) => Dialog(child: CallWatchDialog()),
|
||||
@@ -112,56 +127,48 @@ class DeviceManagementScreen extends ConsumerWidget {
|
||||
iconSize: SizeUtils.getByScreen(small: 42, big: 40),
|
||||
text: context.translate(I18n.callWatch),
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
gap,
|
||||
AppMenuButton(
|
||||
color: theme.getColorFor(ThemeCode.legacyPrimary),
|
||||
color: primaryColor,
|
||||
onPressed: () =>
|
||||
navigationContract.pushTo(AppRoutes.callHistory),
|
||||
icon: Icons.history_outlined,
|
||||
iconSize: SizeUtils.getByScreen(small: 42, big: 40),
|
||||
text: context.translate(I18n.callHistory),
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
AppMenuButton(
|
||||
color: theme.getColorFor(ThemeCode.legacyPrimary),
|
||||
onPressed: () => navigationContract.pushTo(AppRoutes.appsUse),
|
||||
icon: SFIcons.screenTime,
|
||||
text: context.translate(I18n.appsUse),
|
||||
),
|
||||
// SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
// AppMenuButton(
|
||||
// color: theme.getColorFor(ThemeCode.legacyPrimary),
|
||||
// onPressed: () {},
|
||||
// icon: Icons.app_registration_sharp,
|
||||
// text: context.translate(I18n.appsSurveillance),
|
||||
// ),
|
||||
// SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
// AppMenuButton(
|
||||
// color: theme.getColorFor(ThemeCode.legacyPrimary),
|
||||
// onPressed: () {},
|
||||
// icon: SFIcons.friendsCircle,
|
||||
// negativeIcon: true,
|
||||
// text: context.translate(I18n.makeFriends),
|
||||
// ),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
AppMenuButton(
|
||||
color: theme.getColorFor(ThemeCode.legacyPrimary),
|
||||
onPressed: () =>
|
||||
navigationContract.pushTo(AppRoutes.locateDevice),
|
||||
icon: SFIcons.locateSfCircle,
|
||||
negativeIcon: true,
|
||||
text: context.translate(I18n.locateDevicePlaySoundButton),
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
AppMenuButton(
|
||||
color: theme.getColorFor(ThemeCode.legacyPrimary),
|
||||
onPressed: () =>
|
||||
navigationContract.pushTo(AppRoutes.backgroundImage),
|
||||
icon: Icons.add_photo_alternate_outlined,
|
||||
iconSize: SizeUtils.getByScreen(small: 32, big: 30),
|
||||
negativeIcon: false,
|
||||
text: context.translate(I18n.customBackground),
|
||||
),
|
||||
if (capabilities?.appUsageSchedules != null) ...[
|
||||
gap,
|
||||
AppMenuButton(
|
||||
color: primaryColor,
|
||||
onPressed: () =>
|
||||
navigationContract.pushTo(AppRoutes.appsUse),
|
||||
icon: SFIcons.screenTime,
|
||||
text: context.translate(I18n.appsUse),
|
||||
),
|
||||
],
|
||||
if (capabilities?.commands?.types.contains('FIND_DEVICE') ?? false) ...[
|
||||
gap,
|
||||
AppMenuButton(
|
||||
color: primaryColor,
|
||||
onPressed: () =>
|
||||
navigationContract.pushTo(AppRoutes.locateDevice),
|
||||
icon: SFIcons.locateSfCircle,
|
||||
negativeIcon: true,
|
||||
text: context.translate(I18n.locateDevicePlaySoundButton),
|
||||
),
|
||||
],
|
||||
if (capabilities?.deviceBackground?.enabled ?? false) ...[
|
||||
gap,
|
||||
AppMenuButton(
|
||||
color: primaryColor,
|
||||
onPressed: () =>
|
||||
navigationContract.pushTo(AppRoutes.backgroundImage),
|
||||
icon: Icons.add_photo_alternate_outlined,
|
||||
iconSize: SizeUtils.getByScreen(small: 32, big: 30),
|
||||
negativeIcon: false,
|
||||
text: context.translate(I18n.customBackground),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import '../../domain/do_not_disturb_period.dart';
|
||||
|
||||
abstract class DoNotDisturbRemoteDatasource {
|
||||
Future<DoNotDisturbSchedule> getSchedule({required String identificator});
|
||||
Future<DoNotDisturbSchedule> updatePeriods({
|
||||
required String identificator,
|
||||
required List<DoNotDisturbPeriod> periods,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
import 'package:sf_infrastructure/sf_infrastructure.dart';
|
||||
|
||||
import '../../domain/do_not_disturb_period.dart';
|
||||
import '../models/do_not_disturb_response_model.dart';
|
||||
import 'do_not_disturb_remote_datasource.dart';
|
||||
|
||||
class DoNotDisturbRemoteDatasourceImpl implements DoNotDisturbRemoteDatasource {
|
||||
final SaveFamilyRepository _repository;
|
||||
|
||||
DoNotDisturbRemoteDatasourceImpl(this._repository);
|
||||
|
||||
@override
|
||||
Future<DoNotDisturbSchedule> getSchedule({
|
||||
required String identificator,
|
||||
}) async {
|
||||
try {
|
||||
final response = await _repository.get<Map<String, dynamic>>(
|
||||
'/devices/identificator/$identificator/do-not-disturbs',
|
||||
);
|
||||
final model = DoNotDisturbResponseModel.fromJson(response.data!);
|
||||
return _toEntity(model.item);
|
||||
} catch (_) {
|
||||
throw Exception('Error fetching do not disturb schedule');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<DoNotDisturbSchedule> updatePeriods({
|
||||
required String identificator,
|
||||
required List<DoNotDisturbPeriod> periods,
|
||||
}) async {
|
||||
try {
|
||||
final body = {
|
||||
'periods': periods
|
||||
.map(
|
||||
(period) => {
|
||||
'start': period.start,
|
||||
'end': period.end,
|
||||
'week': period.week,
|
||||
},
|
||||
)
|
||||
.toList(),
|
||||
};
|
||||
final response = await _repository.put<Map<String, dynamic>>(
|
||||
'/devices/identificator/$identificator/do-not-disturbs',
|
||||
body: body,
|
||||
);
|
||||
final model = DoNotDisturbUpdateResponseModel.fromJson(response.data!);
|
||||
return _toEntity(model.item);
|
||||
} catch (_) {
|
||||
throw Exception('Error updating do not disturb schedule');
|
||||
}
|
||||
}
|
||||
|
||||
DoNotDisturbSchedule _toEntity(DoNotDisturbItemModel item) =>
|
||||
DoNotDisturbSchedule(
|
||||
id: item.id,
|
||||
deviceIdentificator: item.deviceIdentificator,
|
||||
periods: item.periods
|
||||
.map(
|
||||
(period) => DoNotDisturbPeriod(
|
||||
start: period.start,
|
||||
end: period.end,
|
||||
week: period.week,
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
createdAt: item.createdAt,
|
||||
updatedAt: item.updatedAt,
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'do_not_disturb_response_model.freezed.dart';
|
||||
part 'do_not_disturb_response_model.g.dart';
|
||||
|
||||
@freezed
|
||||
abstract class DoNotDisturbResponseModel with _$DoNotDisturbResponseModel {
|
||||
const factory DoNotDisturbResponseModel({
|
||||
required DoNotDisturbItemModel item,
|
||||
}) = _DoNotDisturbResponseModel;
|
||||
|
||||
factory DoNotDisturbResponseModel.fromJson(Map<String, dynamic> json) =>
|
||||
_$DoNotDisturbResponseModelFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class DoNotDisturbUpdateResponseModel
|
||||
with _$DoNotDisturbUpdateResponseModel {
|
||||
const factory DoNotDisturbUpdateResponseModel({
|
||||
@Default(false) bool isUpdated,
|
||||
required DoNotDisturbItemModel item,
|
||||
}) = _DoNotDisturbUpdateResponseModel;
|
||||
|
||||
factory DoNotDisturbUpdateResponseModel.fromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _$DoNotDisturbUpdateResponseModelFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class DoNotDisturbItemModel with _$DoNotDisturbItemModel {
|
||||
const factory DoNotDisturbItemModel({
|
||||
required String id,
|
||||
required String deviceIdentificator,
|
||||
@Default([]) List<DoNotDisturbPeriodModel> periods,
|
||||
int? createdAt,
|
||||
int? updatedAt,
|
||||
}) = _DoNotDisturbItemModel;
|
||||
|
||||
factory DoNotDisturbItemModel.fromJson(Map<String, dynamic> json) =>
|
||||
_$DoNotDisturbItemModelFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class DoNotDisturbPeriodModel with _$DoNotDisturbPeriodModel {
|
||||
const factory DoNotDisturbPeriodModel({
|
||||
required String start,
|
||||
required String end,
|
||||
required String week,
|
||||
}) = _DoNotDisturbPeriodModel;
|
||||
|
||||
factory DoNotDisturbPeriodModel.fromJson(Map<String, dynamic> json) =>
|
||||
_$DoNotDisturbPeriodModelFromJson(json);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,70 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'do_not_disturb_response_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_DoNotDisturbResponseModel _$DoNotDisturbResponseModelFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _DoNotDisturbResponseModel(
|
||||
item: DoNotDisturbItemModel.fromJson(json['item'] as Map<String, dynamic>),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$DoNotDisturbResponseModelToJson(
|
||||
_DoNotDisturbResponseModel instance,
|
||||
) => <String, dynamic>{'item': instance.item};
|
||||
|
||||
_DoNotDisturbUpdateResponseModel _$DoNotDisturbUpdateResponseModelFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _DoNotDisturbUpdateResponseModel(
|
||||
isUpdated: json['isUpdated'] as bool? ?? false,
|
||||
item: DoNotDisturbItemModel.fromJson(json['item'] as Map<String, dynamic>),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$DoNotDisturbUpdateResponseModelToJson(
|
||||
_DoNotDisturbUpdateResponseModel instance,
|
||||
) => <String, dynamic>{'isUpdated': instance.isUpdated, 'item': instance.item};
|
||||
|
||||
_DoNotDisturbItemModel _$DoNotDisturbItemModelFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _DoNotDisturbItemModel(
|
||||
id: json['id'] as String,
|
||||
deviceIdentificator: json['deviceIdentificator'] as String,
|
||||
periods:
|
||||
(json['periods'] as List<dynamic>?)
|
||||
?.map(
|
||||
(e) => DoNotDisturbPeriodModel.fromJson(e as Map<String, dynamic>),
|
||||
)
|
||||
.toList() ??
|
||||
const [],
|
||||
createdAt: (json['createdAt'] as num?)?.toInt(),
|
||||
updatedAt: (json['updatedAt'] as num?)?.toInt(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$DoNotDisturbItemModelToJson(
|
||||
_DoNotDisturbItemModel instance,
|
||||
) => <String, dynamic>{
|
||||
'id': instance.id,
|
||||
'deviceIdentificator': instance.deviceIdentificator,
|
||||
'periods': instance.periods,
|
||||
'createdAt': instance.createdAt,
|
||||
'updatedAt': instance.updatedAt,
|
||||
};
|
||||
|
||||
_DoNotDisturbPeriodModel _$DoNotDisturbPeriodModelFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _DoNotDisturbPeriodModel(
|
||||
start: json['start'] as String,
|
||||
end: json['end'] as String,
|
||||
week: json['week'] as String,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$DoNotDisturbPeriodModelToJson(
|
||||
_DoNotDisturbPeriodModel instance,
|
||||
) => <String, dynamic>{
|
||||
'start': instance.start,
|
||||
'end': instance.end,
|
||||
'week': instance.week,
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'presentation/do_not_disturb_screen.dart';
|
||||
|
||||
class DoNotDisturbBuilder {
|
||||
const DoNotDisturbBuilder();
|
||||
|
||||
Page<void> buildPage(BuildContext context, GoRouterState state) {
|
||||
return MaterialPage<void>(
|
||||
key: state.pageKey,
|
||||
child: const DoNotDisturbScreen(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'do_not_disturb_period.freezed.dart';
|
||||
|
||||
@freezed
|
||||
abstract class DoNotDisturbPeriod with _$DoNotDisturbPeriod {
|
||||
const factory DoNotDisturbPeriod({
|
||||
required String start,
|
||||
required String end,
|
||||
required String week,
|
||||
}) = _DoNotDisturbPeriod;
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class DoNotDisturbSchedule with _$DoNotDisturbSchedule {
|
||||
const factory DoNotDisturbSchedule({
|
||||
required String id,
|
||||
required String deviceIdentificator,
|
||||
@Default([]) List<DoNotDisturbPeriod> periods,
|
||||
int? createdAt,
|
||||
int? updatedAt,
|
||||
}) = _DoNotDisturbSchedule;
|
||||
}
|
||||
@@ -0,0 +1,552 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'do_not_disturb_period.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$DoNotDisturbPeriod {
|
||||
|
||||
String get start; String get end; String get week;
|
||||
/// Create a copy of DoNotDisturbPeriod
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$DoNotDisturbPeriodCopyWith<DoNotDisturbPeriod> get copyWith => _$DoNotDisturbPeriodCopyWithImpl<DoNotDisturbPeriod>(this as DoNotDisturbPeriod, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is DoNotDisturbPeriod&&(identical(other.start, start) || other.start == start)&&(identical(other.end, end) || other.end == end)&&(identical(other.week, week) || other.week == week));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,start,end,week);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DoNotDisturbPeriod(start: $start, end: $end, week: $week)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $DoNotDisturbPeriodCopyWith<$Res> {
|
||||
factory $DoNotDisturbPeriodCopyWith(DoNotDisturbPeriod value, $Res Function(DoNotDisturbPeriod) _then) = _$DoNotDisturbPeriodCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String start, String end, String week
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$DoNotDisturbPeriodCopyWithImpl<$Res>
|
||||
implements $DoNotDisturbPeriodCopyWith<$Res> {
|
||||
_$DoNotDisturbPeriodCopyWithImpl(this._self, this._then);
|
||||
|
||||
final DoNotDisturbPeriod _self;
|
||||
final $Res Function(DoNotDisturbPeriod) _then;
|
||||
|
||||
/// Create a copy of DoNotDisturbPeriod
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? start = null,Object? end = null,Object? week = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
start: null == start ? _self.start : start // ignore: cast_nullable_to_non_nullable
|
||||
as String,end: null == end ? _self.end : end // ignore: cast_nullable_to_non_nullable
|
||||
as String,week: null == week ? _self.week : week // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [DoNotDisturbPeriod].
|
||||
extension DoNotDisturbPeriodPatterns on DoNotDisturbPeriod {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _DoNotDisturbPeriod value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _DoNotDisturbPeriod() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _DoNotDisturbPeriod value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _DoNotDisturbPeriod():
|
||||
return $default(_that);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _DoNotDisturbPeriod value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _DoNotDisturbPeriod() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String start, String end, String week)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _DoNotDisturbPeriod() when $default != null:
|
||||
return $default(_that.start,_that.end,_that.week);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String start, String end, String week) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _DoNotDisturbPeriod():
|
||||
return $default(_that.start,_that.end,_that.week);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String start, String end, String week)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _DoNotDisturbPeriod() when $default != null:
|
||||
return $default(_that.start,_that.end,_that.week);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _DoNotDisturbPeriod implements DoNotDisturbPeriod {
|
||||
const _DoNotDisturbPeriod({required this.start, required this.end, required this.week});
|
||||
|
||||
|
||||
@override final String start;
|
||||
@override final String end;
|
||||
@override final String week;
|
||||
|
||||
/// Create a copy of DoNotDisturbPeriod
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$DoNotDisturbPeriodCopyWith<_DoNotDisturbPeriod> get copyWith => __$DoNotDisturbPeriodCopyWithImpl<_DoNotDisturbPeriod>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _DoNotDisturbPeriod&&(identical(other.start, start) || other.start == start)&&(identical(other.end, end) || other.end == end)&&(identical(other.week, week) || other.week == week));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,start,end,week);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DoNotDisturbPeriod(start: $start, end: $end, week: $week)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$DoNotDisturbPeriodCopyWith<$Res> implements $DoNotDisturbPeriodCopyWith<$Res> {
|
||||
factory _$DoNotDisturbPeriodCopyWith(_DoNotDisturbPeriod value, $Res Function(_DoNotDisturbPeriod) _then) = __$DoNotDisturbPeriodCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String start, String end, String week
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$DoNotDisturbPeriodCopyWithImpl<$Res>
|
||||
implements _$DoNotDisturbPeriodCopyWith<$Res> {
|
||||
__$DoNotDisturbPeriodCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _DoNotDisturbPeriod _self;
|
||||
final $Res Function(_DoNotDisturbPeriod) _then;
|
||||
|
||||
/// Create a copy of DoNotDisturbPeriod
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? start = null,Object? end = null,Object? week = null,}) {
|
||||
return _then(_DoNotDisturbPeriod(
|
||||
start: null == start ? _self.start : start // ignore: cast_nullable_to_non_nullable
|
||||
as String,end: null == end ? _self.end : end // ignore: cast_nullable_to_non_nullable
|
||||
as String,week: null == week ? _self.week : week // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$DoNotDisturbSchedule {
|
||||
|
||||
String get id; String get deviceIdentificator; List<DoNotDisturbPeriod> get periods; int? get createdAt; int? get updatedAt;
|
||||
/// Create a copy of DoNotDisturbSchedule
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$DoNotDisturbScheduleCopyWith<DoNotDisturbSchedule> get copyWith => _$DoNotDisturbScheduleCopyWithImpl<DoNotDisturbSchedule>(this as DoNotDisturbSchedule, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is DoNotDisturbSchedule&&(identical(other.id, id) || other.id == id)&&(identical(other.deviceIdentificator, deviceIdentificator) || other.deviceIdentificator == deviceIdentificator)&&const DeepCollectionEquality().equals(other.periods, periods)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,id,deviceIdentificator,const DeepCollectionEquality().hash(periods),createdAt,updatedAt);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DoNotDisturbSchedule(id: $id, deviceIdentificator: $deviceIdentificator, periods: $periods, createdAt: $createdAt, updatedAt: $updatedAt)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $DoNotDisturbScheduleCopyWith<$Res> {
|
||||
factory $DoNotDisturbScheduleCopyWith(DoNotDisturbSchedule value, $Res Function(DoNotDisturbSchedule) _then) = _$DoNotDisturbScheduleCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String id, String deviceIdentificator, List<DoNotDisturbPeriod> periods, int? createdAt, int? updatedAt
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$DoNotDisturbScheduleCopyWithImpl<$Res>
|
||||
implements $DoNotDisturbScheduleCopyWith<$Res> {
|
||||
_$DoNotDisturbScheduleCopyWithImpl(this._self, this._then);
|
||||
|
||||
final DoNotDisturbSchedule _self;
|
||||
final $Res Function(DoNotDisturbSchedule) _then;
|
||||
|
||||
/// Create a copy of DoNotDisturbSchedule
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? deviceIdentificator = null,Object? periods = null,Object? createdAt = freezed,Object? updatedAt = freezed,}) {
|
||||
return _then(_self.copyWith(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,deviceIdentificator: null == deviceIdentificator ? _self.deviceIdentificator : deviceIdentificator // ignore: cast_nullable_to_non_nullable
|
||||
as String,periods: null == periods ? _self.periods : periods // ignore: cast_nullable_to_non_nullable
|
||||
as List<DoNotDisturbPeriod>,createdAt: freezed == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as int?,updatedAt: freezed == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||
as int?,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [DoNotDisturbSchedule].
|
||||
extension DoNotDisturbSchedulePatterns on DoNotDisturbSchedule {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _DoNotDisturbSchedule value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _DoNotDisturbSchedule() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _DoNotDisturbSchedule value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _DoNotDisturbSchedule():
|
||||
return $default(_that);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _DoNotDisturbSchedule value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _DoNotDisturbSchedule() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String deviceIdentificator, List<DoNotDisturbPeriod> periods, int? createdAt, int? updatedAt)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _DoNotDisturbSchedule() when $default != null:
|
||||
return $default(_that.id,_that.deviceIdentificator,_that.periods,_that.createdAt,_that.updatedAt);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String deviceIdentificator, List<DoNotDisturbPeriod> periods, int? createdAt, int? updatedAt) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _DoNotDisturbSchedule():
|
||||
return $default(_that.id,_that.deviceIdentificator,_that.periods,_that.createdAt,_that.updatedAt);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String deviceIdentificator, List<DoNotDisturbPeriod> periods, int? createdAt, int? updatedAt)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _DoNotDisturbSchedule() when $default != null:
|
||||
return $default(_that.id,_that.deviceIdentificator,_that.periods,_that.createdAt,_that.updatedAt);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _DoNotDisturbSchedule implements DoNotDisturbSchedule {
|
||||
const _DoNotDisturbSchedule({required this.id, required this.deviceIdentificator, final List<DoNotDisturbPeriod> periods = const [], this.createdAt, this.updatedAt}): _periods = periods;
|
||||
|
||||
|
||||
@override final String id;
|
||||
@override final String deviceIdentificator;
|
||||
final List<DoNotDisturbPeriod> _periods;
|
||||
@override@JsonKey() List<DoNotDisturbPeriod> get periods {
|
||||
if (_periods is EqualUnmodifiableListView) return _periods;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_periods);
|
||||
}
|
||||
|
||||
@override final int? createdAt;
|
||||
@override final int? updatedAt;
|
||||
|
||||
/// Create a copy of DoNotDisturbSchedule
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$DoNotDisturbScheduleCopyWith<_DoNotDisturbSchedule> get copyWith => __$DoNotDisturbScheduleCopyWithImpl<_DoNotDisturbSchedule>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _DoNotDisturbSchedule&&(identical(other.id, id) || other.id == id)&&(identical(other.deviceIdentificator, deviceIdentificator) || other.deviceIdentificator == deviceIdentificator)&&const DeepCollectionEquality().equals(other._periods, _periods)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,id,deviceIdentificator,const DeepCollectionEquality().hash(_periods),createdAt,updatedAt);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DoNotDisturbSchedule(id: $id, deviceIdentificator: $deviceIdentificator, periods: $periods, createdAt: $createdAt, updatedAt: $updatedAt)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$DoNotDisturbScheduleCopyWith<$Res> implements $DoNotDisturbScheduleCopyWith<$Res> {
|
||||
factory _$DoNotDisturbScheduleCopyWith(_DoNotDisturbSchedule value, $Res Function(_DoNotDisturbSchedule) _then) = __$DoNotDisturbScheduleCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String id, String deviceIdentificator, List<DoNotDisturbPeriod> periods, int? createdAt, int? updatedAt
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$DoNotDisturbScheduleCopyWithImpl<$Res>
|
||||
implements _$DoNotDisturbScheduleCopyWith<$Res> {
|
||||
__$DoNotDisturbScheduleCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _DoNotDisturbSchedule _self;
|
||||
final $Res Function(_DoNotDisturbSchedule) _then;
|
||||
|
||||
/// Create a copy of DoNotDisturbSchedule
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? deviceIdentificator = null,Object? periods = null,Object? createdAt = freezed,Object? updatedAt = freezed,}) {
|
||||
return _then(_DoNotDisturbSchedule(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,deviceIdentificator: null == deviceIdentificator ? _self.deviceIdentificator : deviceIdentificator // ignore: cast_nullable_to_non_nullable
|
||||
as String,periods: null == periods ? _self._periods : periods // ignore: cast_nullable_to_non_nullable
|
||||
as List<DoNotDisturbPeriod>,createdAt: freezed == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as int?,updatedAt: freezed == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||
as int?,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -0,0 +1,192 @@
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:legacy_shared/legacy_shared.dart';
|
||||
import 'package:sf_localizations/sf_localizations.dart';
|
||||
import 'package:utils/utils.dart';
|
||||
|
||||
import '../domain/do_not_disturb_period.dart';
|
||||
import 'state/do_not_disturb_view_model.dart';
|
||||
import 'state/do_not_disturb_view_state.dart';
|
||||
import 'widgets/do_not_disturb_period_card.dart';
|
||||
import 'widgets/edit_period_sheet.dart';
|
||||
|
||||
class DoNotDisturbScreen extends ConsumerWidget {
|
||||
const DoNotDisturbScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final theme = ref.watch(themePortProvider);
|
||||
final vm = ref.read(doNotDisturbViewModelProvider.notifier);
|
||||
final (periods, maxPeriods, isLoading, isSaving) = ref.watch(
|
||||
doNotDisturbViewModelProvider.select(
|
||||
(s) => (s.periods, s.maxPeriods, s.isLoading, s.isSaving),
|
||||
),
|
||||
);
|
||||
|
||||
ref.listen(doNotDisturbViewModelProvider.select((s) => s.errorEvent), (
|
||||
_,
|
||||
next,
|
||||
) {
|
||||
if (next == null) return;
|
||||
final message = switch (next) {
|
||||
DoNotDisturbErrorEvent.load || DoNotDisturbErrorEvent.save => context.translate(
|
||||
I18n.doNotDisturbError,
|
||||
),
|
||||
DoNotDisturbErrorEvent.maxPeriods => context
|
||||
.translate(I18n.doNotDisturbMaxPeriods)
|
||||
.replaceAll('{max}', maxPeriods.toString()),
|
||||
};
|
||||
showTopSnackbar(context, message: message, type: MessageType.error);
|
||||
vm.clearError();
|
||||
});
|
||||
|
||||
ref.listen(doNotDisturbViewModelProvider.select((s) => s.saveSuccess), (
|
||||
_,
|
||||
success,
|
||||
) {
|
||||
if (success) {
|
||||
showTopSnackbar(
|
||||
context,
|
||||
message: context.translate(I18n.doNotDisturbSaved),
|
||||
type: MessageType.success,
|
||||
);
|
||||
vm.clearSaveSuccess();
|
||||
}
|
||||
});
|
||||
|
||||
final primaryColor = theme.getColorFor(ThemeCode.legacyPrimary);
|
||||
|
||||
return LegacyPageLayout(
|
||||
theme: theme,
|
||||
title: context.translate(I18n.doNotDisturb),
|
||||
body: isLoading
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: SingleChildScrollView(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: SizeUtils.getByScreen(small: 16, big: 14),
|
||||
vertical: SizeUtils.getByScreen(small: 12, big: 10),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Text(
|
||||
context.translate(I18n.doNotDisturbDescription),
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 13, big: 12),
|
||||
color: theme
|
||||
.getColorFor(ThemeCode.textPrimary)
|
||||
.withValues(alpha: 0.5),
|
||||
height: 1.4,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: SizeUtils.getByScreen(small: 16, big: 14),
|
||||
),
|
||||
...periods.asMap().entries.map((entry) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(
|
||||
bottom: SizeUtils.getByScreen(small: 8, big: 6),
|
||||
),
|
||||
child: DoNotDisturbPeriodCard(
|
||||
period: entry.value,
|
||||
onEdit: () => _editPeriod(
|
||||
context,
|
||||
vm,
|
||||
entry.key,
|
||||
entry.value,
|
||||
),
|
||||
onDelete: () => vm.removePeriod(entry.key),
|
||||
),
|
||||
);
|
||||
}),
|
||||
if (periods.isEmpty)
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: SizeUtils.getByScreen(small: 24, big: 20),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
context.translate(I18n.doNotDisturbEmpty),
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(
|
||||
small: 14,
|
||||
big: 13,
|
||||
),
|
||||
color: theme
|
||||
.getColorFor(ThemeCode.textPrimary)
|
||||
.withValues(alpha: 0.4),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (periods.length < maxPeriods)
|
||||
Padding(
|
||||
padding: EdgeInsets.only(
|
||||
top: SizeUtils.getByScreen(small: 8, big: 6),
|
||||
),
|
||||
child: OutlinedButton.icon(
|
||||
onPressed: () => _addPeriod(context, vm),
|
||||
icon: const Icon(Icons.add),
|
||||
label: Text(
|
||||
context.translate(I18n.doNotDisturbAddPeriod),
|
||||
),
|
||||
style: OutlinedButton.styleFrom(
|
||||
foregroundColor: primaryColor,
|
||||
side: BorderSide(color: primaryColor),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(
|
||||
SizeUtils.getByScreen(small: 12, big: 10),
|
||||
),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: SizeUtils.getByScreen(
|
||||
small: 12,
|
||||
big: 10,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
footer: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 10),
|
||||
child: isSaving
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: PrimaryButton(
|
||||
onPressed: vm.save,
|
||||
text: context.translate(I18n.doNotDisturbSave),
|
||||
color: primaryColor,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _addPeriod(
|
||||
BuildContext context,
|
||||
DoNotDisturbViewModel vm,
|
||||
) async {
|
||||
final period = await showModalBottomSheet<DoNotDisturbPeriod>(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
builder: (_) => const EditPeriodSheet(),
|
||||
);
|
||||
if (period != null) vm.addPeriod(period);
|
||||
}
|
||||
|
||||
Future<void> _editPeriod(
|
||||
BuildContext context,
|
||||
DoNotDisturbViewModel vm,
|
||||
int index,
|
||||
DoNotDisturbPeriod existing,
|
||||
) async {
|
||||
final period = await showModalBottomSheet<DoNotDisturbPeriod>(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
builder: (_) => EditPeriodSheet(initial: existing),
|
||||
);
|
||||
if (period != null) vm.updatePeriod(index, period);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:legacy_shared/legacy_shared.dart';
|
||||
import 'package:sf_tracking/sf_tracking.dart';
|
||||
|
||||
import '../../data/datasource/do_not_disturb_remote_datasource.dart';
|
||||
import '../../domain/do_not_disturb_period.dart';
|
||||
import '../../providers/do_not_disturb_providers.dart';
|
||||
import 'do_not_disturb_view_state.dart';
|
||||
|
||||
final doNotDisturbViewModelProvider =
|
||||
NotifierProvider.autoDispose<
|
||||
DoNotDisturbViewModel,
|
||||
DoNotDisturbViewState
|
||||
>(DoNotDisturbViewModel.new);
|
||||
|
||||
class DoNotDisturbViewModel extends Notifier<DoNotDisturbViewState> {
|
||||
late final DoNotDisturbRemoteDatasource _datasource;
|
||||
late final SfTrackingRepository _tracking;
|
||||
|
||||
@override
|
||||
DoNotDisturbViewState build() {
|
||||
_datasource = ref.read(doNotDisturbRemoteDatasourceProvider);
|
||||
_tracking = ref.read(sfTrackingProvider);
|
||||
Future.microtask(_load);
|
||||
return const DoNotDisturbViewState();
|
||||
}
|
||||
|
||||
String? get _identificator =>
|
||||
ref.read(selectedDeviceProvider).value?.identificator;
|
||||
|
||||
Future<void> _load() async {
|
||||
final identificator = _identificator;
|
||||
if (identificator == null) {
|
||||
state = state.copyWith(isLoading: false);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
final schedule = await _datasource.getSchedule(
|
||||
identificator: identificator,
|
||||
);
|
||||
if (!ref.mounted) return;
|
||||
|
||||
final device = ref.read(selectedDeviceProvider).value;
|
||||
final capabilities = device?.capabilities;
|
||||
final maxPeriods = capabilities?.doNotDisturbs?.maxPeriods ?? 4;
|
||||
|
||||
state = state.copyWith(
|
||||
isLoading: false,
|
||||
periods: schedule.periods,
|
||||
maxPeriods: maxPeriods,
|
||||
);
|
||||
} catch (_) {
|
||||
if (!ref.mounted) return;
|
||||
state = state.copyWith(
|
||||
isLoading: false,
|
||||
errorEvent: DoNotDisturbErrorEvent.load,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void addPeriod(DoNotDisturbPeriod period) {
|
||||
if (state.periods.length >= state.maxPeriods) {
|
||||
state = state.copyWith(errorEvent: DoNotDisturbErrorEvent.maxPeriods);
|
||||
return;
|
||||
}
|
||||
state = state.copyWith(
|
||||
periods: [...state.periods, period],
|
||||
errorEvent: null,
|
||||
);
|
||||
}
|
||||
|
||||
void updatePeriod(int index, DoNotDisturbPeriod period) {
|
||||
if (index < 0 || index >= state.periods.length) return;
|
||||
final updated = [...state.periods];
|
||||
updated[index] = period;
|
||||
state = state.copyWith(periods: updated, errorEvent: null);
|
||||
}
|
||||
|
||||
void removePeriod(int index) {
|
||||
if (index < 0 || index >= state.periods.length) return;
|
||||
final updated = [...state.periods]..removeAt(index);
|
||||
state = state.copyWith(periods: updated, errorEvent: null);
|
||||
}
|
||||
|
||||
void clearError() {
|
||||
if (state.errorEvent != null) state = state.copyWith(errorEvent: null);
|
||||
}
|
||||
|
||||
void clearSaveSuccess() {
|
||||
if (state.saveSuccess) state = state.copyWith(saveSuccess: false);
|
||||
}
|
||||
|
||||
Future<void> save() async {
|
||||
final identificator = _identificator;
|
||||
if (identificator == null) return;
|
||||
|
||||
state = state.copyWith(
|
||||
isSaving: true,
|
||||
saveSuccess: false,
|
||||
errorEvent: null,
|
||||
);
|
||||
|
||||
try {
|
||||
final schedule = await _datasource.updatePeriods(
|
||||
identificator: identificator,
|
||||
periods: state.periods,
|
||||
);
|
||||
if (!ref.mounted) return;
|
||||
|
||||
state = state.copyWith(
|
||||
isSaving: false,
|
||||
periods: schedule.periods,
|
||||
saveSuccess: true,
|
||||
);
|
||||
|
||||
unawaited(
|
||||
_tracking.legacyDeviceDoNotDisturbScheduleSaved(
|
||||
schedule.periods.length,
|
||||
),
|
||||
);
|
||||
} catch (_) {
|
||||
if (!ref.mounted) return;
|
||||
state = state.copyWith(
|
||||
isSaving: false,
|
||||
errorEvent: DoNotDisturbErrorEvent.save,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
import '../../domain/do_not_disturb_period.dart';
|
||||
|
||||
part 'do_not_disturb_view_state.freezed.dart';
|
||||
|
||||
enum DoNotDisturbErrorEvent { load, save, maxPeriods }
|
||||
|
||||
@freezed
|
||||
abstract class DoNotDisturbViewState with _$DoNotDisturbViewState {
|
||||
const factory DoNotDisturbViewState({
|
||||
@Default(true) bool isLoading,
|
||||
@Default(false) bool isSaving,
|
||||
@Default([]) List<DoNotDisturbPeriod> periods,
|
||||
@Default(4) int maxPeriods,
|
||||
DoNotDisturbErrorEvent? errorEvent,
|
||||
@Default(false) bool saveSuccess,
|
||||
}) = _DoNotDisturbViewState;
|
||||
}
|
||||
@@ -0,0 +1,292 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'do_not_disturb_view_state.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$DoNotDisturbViewState {
|
||||
|
||||
bool get isLoading; bool get isSaving; List<DoNotDisturbPeriod> get periods; int get maxPeriods; DoNotDisturbErrorEvent? get errorEvent; bool get saveSuccess;
|
||||
/// Create a copy of DoNotDisturbViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$DoNotDisturbViewStateCopyWith<DoNotDisturbViewState> get copyWith => _$DoNotDisturbViewStateCopyWithImpl<DoNotDisturbViewState>(this as DoNotDisturbViewState, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is DoNotDisturbViewState&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.isSaving, isSaving) || other.isSaving == isSaving)&&const DeepCollectionEquality().equals(other.periods, periods)&&(identical(other.maxPeriods, maxPeriods) || other.maxPeriods == maxPeriods)&&(identical(other.errorEvent, errorEvent) || other.errorEvent == errorEvent)&&(identical(other.saveSuccess, saveSuccess) || other.saveSuccess == saveSuccess));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,isLoading,isSaving,const DeepCollectionEquality().hash(periods),maxPeriods,errorEvent,saveSuccess);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DoNotDisturbViewState(isLoading: $isLoading, isSaving: $isSaving, periods: $periods, maxPeriods: $maxPeriods, errorEvent: $errorEvent, saveSuccess: $saveSuccess)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $DoNotDisturbViewStateCopyWith<$Res> {
|
||||
factory $DoNotDisturbViewStateCopyWith(DoNotDisturbViewState value, $Res Function(DoNotDisturbViewState) _then) = _$DoNotDisturbViewStateCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
bool isLoading, bool isSaving, List<DoNotDisturbPeriod> periods, int maxPeriods, DoNotDisturbErrorEvent? errorEvent, bool saveSuccess
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$DoNotDisturbViewStateCopyWithImpl<$Res>
|
||||
implements $DoNotDisturbViewStateCopyWith<$Res> {
|
||||
_$DoNotDisturbViewStateCopyWithImpl(this._self, this._then);
|
||||
|
||||
final DoNotDisturbViewState _self;
|
||||
final $Res Function(DoNotDisturbViewState) _then;
|
||||
|
||||
/// Create a copy of DoNotDisturbViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? isLoading = null,Object? isSaving = null,Object? periods = null,Object? maxPeriods = null,Object? errorEvent = freezed,Object? saveSuccess = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable
|
||||
as bool,isSaving: null == isSaving ? _self.isSaving : isSaving // ignore: cast_nullable_to_non_nullable
|
||||
as bool,periods: null == periods ? _self.periods : periods // ignore: cast_nullable_to_non_nullable
|
||||
as List<DoNotDisturbPeriod>,maxPeriods: null == maxPeriods ? _self.maxPeriods : maxPeriods // ignore: cast_nullable_to_non_nullable
|
||||
as int,errorEvent: freezed == errorEvent ? _self.errorEvent : errorEvent // ignore: cast_nullable_to_non_nullable
|
||||
as DoNotDisturbErrorEvent?,saveSuccess: null == saveSuccess ? _self.saveSuccess : saveSuccess // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [DoNotDisturbViewState].
|
||||
extension DoNotDisturbViewStatePatterns on DoNotDisturbViewState {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _DoNotDisturbViewState value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _DoNotDisturbViewState() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _DoNotDisturbViewState value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _DoNotDisturbViewState():
|
||||
return $default(_that);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _DoNotDisturbViewState value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _DoNotDisturbViewState() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( bool isLoading, bool isSaving, List<DoNotDisturbPeriod> periods, int maxPeriods, DoNotDisturbErrorEvent? errorEvent, bool saveSuccess)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _DoNotDisturbViewState() when $default != null:
|
||||
return $default(_that.isLoading,_that.isSaving,_that.periods,_that.maxPeriods,_that.errorEvent,_that.saveSuccess);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( bool isLoading, bool isSaving, List<DoNotDisturbPeriod> periods, int maxPeriods, DoNotDisturbErrorEvent? errorEvent, bool saveSuccess) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _DoNotDisturbViewState():
|
||||
return $default(_that.isLoading,_that.isSaving,_that.periods,_that.maxPeriods,_that.errorEvent,_that.saveSuccess);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( bool isLoading, bool isSaving, List<DoNotDisturbPeriod> periods, int maxPeriods, DoNotDisturbErrorEvent? errorEvent, bool saveSuccess)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _DoNotDisturbViewState() when $default != null:
|
||||
return $default(_that.isLoading,_that.isSaving,_that.periods,_that.maxPeriods,_that.errorEvent,_that.saveSuccess);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _DoNotDisturbViewState implements DoNotDisturbViewState {
|
||||
const _DoNotDisturbViewState({this.isLoading = true, this.isSaving = false, final List<DoNotDisturbPeriod> periods = const [], this.maxPeriods = 4, this.errorEvent, this.saveSuccess = false}): _periods = periods;
|
||||
|
||||
|
||||
@override@JsonKey() final bool isLoading;
|
||||
@override@JsonKey() final bool isSaving;
|
||||
final List<DoNotDisturbPeriod> _periods;
|
||||
@override@JsonKey() List<DoNotDisturbPeriod> get periods {
|
||||
if (_periods is EqualUnmodifiableListView) return _periods;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_periods);
|
||||
}
|
||||
|
||||
@override@JsonKey() final int maxPeriods;
|
||||
@override final DoNotDisturbErrorEvent? errorEvent;
|
||||
@override@JsonKey() final bool saveSuccess;
|
||||
|
||||
/// Create a copy of DoNotDisturbViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$DoNotDisturbViewStateCopyWith<_DoNotDisturbViewState> get copyWith => __$DoNotDisturbViewStateCopyWithImpl<_DoNotDisturbViewState>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _DoNotDisturbViewState&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.isSaving, isSaving) || other.isSaving == isSaving)&&const DeepCollectionEquality().equals(other._periods, _periods)&&(identical(other.maxPeriods, maxPeriods) || other.maxPeriods == maxPeriods)&&(identical(other.errorEvent, errorEvent) || other.errorEvent == errorEvent)&&(identical(other.saveSuccess, saveSuccess) || other.saveSuccess == saveSuccess));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,isLoading,isSaving,const DeepCollectionEquality().hash(_periods),maxPeriods,errorEvent,saveSuccess);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DoNotDisturbViewState(isLoading: $isLoading, isSaving: $isSaving, periods: $periods, maxPeriods: $maxPeriods, errorEvent: $errorEvent, saveSuccess: $saveSuccess)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$DoNotDisturbViewStateCopyWith<$Res> implements $DoNotDisturbViewStateCopyWith<$Res> {
|
||||
factory _$DoNotDisturbViewStateCopyWith(_DoNotDisturbViewState value, $Res Function(_DoNotDisturbViewState) _then) = __$DoNotDisturbViewStateCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
bool isLoading, bool isSaving, List<DoNotDisturbPeriod> periods, int maxPeriods, DoNotDisturbErrorEvent? errorEvent, bool saveSuccess
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$DoNotDisturbViewStateCopyWithImpl<$Res>
|
||||
implements _$DoNotDisturbViewStateCopyWith<$Res> {
|
||||
__$DoNotDisturbViewStateCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _DoNotDisturbViewState _self;
|
||||
final $Res Function(_DoNotDisturbViewState) _then;
|
||||
|
||||
/// Create a copy of DoNotDisturbViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? isLoading = null,Object? isSaving = null,Object? periods = null,Object? maxPeriods = null,Object? errorEvent = freezed,Object? saveSuccess = null,}) {
|
||||
return _then(_DoNotDisturbViewState(
|
||||
isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable
|
||||
as bool,isSaving: null == isSaving ? _self.isSaving : isSaving // ignore: cast_nullable_to_non_nullable
|
||||
as bool,periods: null == periods ? _self._periods : periods // ignore: cast_nullable_to_non_nullable
|
||||
as List<DoNotDisturbPeriod>,maxPeriods: null == maxPeriods ? _self.maxPeriods : maxPeriods // ignore: cast_nullable_to_non_nullable
|
||||
as int,errorEvent: freezed == errorEvent ? _self.errorEvent : errorEvent // ignore: cast_nullable_to_non_nullable
|
||||
as DoNotDisturbErrorEvent?,saveSuccess: null == saveSuccess ? _self.saveSuccess : saveSuccess // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -0,0 +1,80 @@
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:utils/utils.dart';
|
||||
|
||||
import '../../domain/do_not_disturb_period.dart';
|
||||
import 'week_day_row.dart';
|
||||
|
||||
class DoNotDisturbPeriodCard extends ConsumerWidget {
|
||||
final DoNotDisturbPeriod period;
|
||||
final VoidCallback onEdit;
|
||||
final VoidCallback onDelete;
|
||||
|
||||
const DoNotDisturbPeriodCard({
|
||||
super.key,
|
||||
required this.period,
|
||||
required this.onEdit,
|
||||
required this.onDelete,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final theme = ref.watch(themePortProvider);
|
||||
final primaryColor = theme.getColorFor(ThemeCode.legacyPrimary);
|
||||
|
||||
return Container(
|
||||
padding: EdgeInsets.all(SizeUtils.getByScreen(small: 14, big: 12)),
|
||||
decoration: BoxDecoration(
|
||||
color: theme.getColorFor(ThemeCode.backgroundSecondary),
|
||||
borderRadius: BorderRadius.circular(
|
||||
SizeUtils.getByScreen(small: 12, big: 10),
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.schedule,
|
||||
color: primaryColor,
|
||||
size: SizeUtils.getByScreen(small: 20, big: 18),
|
||||
),
|
||||
SizedBox(width: SizeUtils.getByScreen(small: 8, big: 6)),
|
||||
Expanded(
|
||||
child: Text(
|
||||
'${period.start} — ${period.end}',
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 16, big: 15),
|
||||
fontWeight: FontWeight.w600,
|
||||
color: theme.getColorFor(ThemeCode.textPrimary),
|
||||
),
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: onEdit,
|
||||
child: Icon(
|
||||
Icons.edit_outlined,
|
||||
size: SizeUtils.getByScreen(small: 20, big: 18),
|
||||
color: primaryColor,
|
||||
),
|
||||
),
|
||||
SizedBox(width: SizeUtils.getByScreen(small: 12, big: 10)),
|
||||
GestureDetector(
|
||||
onTap: onDelete,
|
||||
child: Icon(
|
||||
Icons.delete_outline,
|
||||
size: SizeUtils.getByScreen(small: 20, big: 18),
|
||||
color: Colors.red.shade400,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 8, big: 6)),
|
||||
WeekDayRow(week: period.week, activeColor: primaryColor),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:sf_localizations/sf_localizations.dart';
|
||||
import 'package:utils/utils.dart';
|
||||
|
||||
import '../../domain/do_not_disturb_period.dart';
|
||||
import 'week_day_row.dart';
|
||||
|
||||
class EditPeriodSheet extends ConsumerStatefulWidget {
|
||||
final DoNotDisturbPeriod? initial;
|
||||
|
||||
const EditPeriodSheet({super.key, this.initial});
|
||||
|
||||
@override
|
||||
ConsumerState<EditPeriodSheet> createState() => _EditPeriodSheetState();
|
||||
}
|
||||
|
||||
class _EditPeriodSheetState extends ConsumerState<EditPeriodSheet> {
|
||||
late TimeOfDay _start;
|
||||
late TimeOfDay _end;
|
||||
late List<bool> _weekDays;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (widget.initial != null) {
|
||||
_start = _parseTime(widget.initial!.start);
|
||||
_end = _parseTime(widget.initial!.end);
|
||||
_weekDays = widget.initial!.week
|
||||
.padRight(7, '0')
|
||||
.split('')
|
||||
.map((c) => c == '1')
|
||||
.toList();
|
||||
} else {
|
||||
_start = const TimeOfDay(hour: 22, minute: 0);
|
||||
_end = const TimeOfDay(hour: 7, minute: 0);
|
||||
_weekDays = [true, true, true, true, true, true, true];
|
||||
}
|
||||
}
|
||||
|
||||
TimeOfDay _parseTime(String time) {
|
||||
final parts = time.split(':');
|
||||
return TimeOfDay(
|
||||
hour: int.tryParse(parts[0]) ?? 0,
|
||||
minute: int.tryParse(parts.length > 1 ? parts[1] : '0') ?? 0,
|
||||
);
|
||||
}
|
||||
|
||||
String _formatForApi(TimeOfDay t) =>
|
||||
'${t.hour}:${t.minute.toString().padLeft(2, '0')}';
|
||||
|
||||
String _formatForDisplay(TimeOfDay t) =>
|
||||
'${t.hour.toString().padLeft(2, '0')}:${t.minute.toString().padLeft(2, '0')}';
|
||||
|
||||
String _weekToString() => _weekDays.map((d) => d ? '1' : '0').join();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = ref.watch(themePortProvider);
|
||||
final primaryColor = theme.getColorFor(ThemeCode.legacyPrimary);
|
||||
final isEditing = widget.initial != null;
|
||||
final hasSelectedDays = _weekDays.any((d) => d);
|
||||
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(
|
||||
bottom: MediaQuery.viewInsetsOf(context).bottom,
|
||||
left: SizeUtils.getByScreen(small: 20, big: 18),
|
||||
right: SizeUtils.getByScreen(small: 20, big: 18),
|
||||
top: SizeUtils.getByScreen(small: 20, big: 18),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Text(
|
||||
context.translate(
|
||||
isEditing
|
||||
? I18n.doNotDisturbEditPeriod
|
||||
: I18n.doNotDisturbAddPeriod,
|
||||
),
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 18, big: 16),
|
||||
fontWeight: FontWeight.w700,
|
||||
color: theme.getColorFor(ThemeCode.textPrimary),
|
||||
),
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 20, big: 18)),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: _TimePickerTile(
|
||||
label: context.translate(I18n.doNotDisturbStart),
|
||||
value: _formatForDisplay(_start),
|
||||
color: primaryColor,
|
||||
onTap: () async {
|
||||
final picked = await showTimePicker(
|
||||
context: context,
|
||||
initialTime: _start,
|
||||
);
|
||||
if (picked != null) setState(() => _start = picked);
|
||||
},
|
||||
),
|
||||
),
|
||||
SizedBox(width: SizeUtils.getByScreen(small: 12, big: 10)),
|
||||
Expanded(
|
||||
child: _TimePickerTile(
|
||||
label: context.translate(I18n.doNotDisturbEnd),
|
||||
value: _formatForDisplay(_end),
|
||||
color: primaryColor,
|
||||
onTap: () async {
|
||||
final picked = await showTimePicker(
|
||||
context: context,
|
||||
initialTime: _end,
|
||||
);
|
||||
if (picked != null) setState(() => _end = picked);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 20, big: 18)),
|
||||
Text(
|
||||
context.translate(I18n.doNotDisturbDays),
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 14, big: 13),
|
||||
fontWeight: FontWeight.w600,
|
||||
color: theme.getColorFor(ThemeCode.textPrimary),
|
||||
),
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 10, big: 8)),
|
||||
WeekDayRow(
|
||||
week: _weekToString(),
|
||||
activeColor: primaryColor,
|
||||
readOnly: false,
|
||||
onToggle: (index) =>
|
||||
setState(() => _weekDays[index] = !_weekDays[index]),
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 24, big: 20)),
|
||||
PrimaryButton(
|
||||
onPressed: hasSelectedDays
|
||||
? () {
|
||||
Navigator.pop(
|
||||
context,
|
||||
DoNotDisturbPeriod(
|
||||
start: _formatForApi(_start),
|
||||
end: _formatForApi(_end),
|
||||
week: _weekToString(),
|
||||
),
|
||||
);
|
||||
}
|
||||
: null,
|
||||
text: context.translate(I18n.doNotDisturbConfirm),
|
||||
color: primaryColor,
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 12, big: 10)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _TimePickerTile extends StatelessWidget {
|
||||
final String label;
|
||||
final String value;
|
||||
final Color color;
|
||||
final VoidCallback onTap;
|
||||
|
||||
const _TimePickerTile({
|
||||
required this.label,
|
||||
required this.value,
|
||||
required this.color,
|
||||
required this.onTap,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: SizeUtils.getByScreen(small: 14, big: 12),
|
||||
vertical: SizeUtils.getByScreen(small: 12, big: 10),
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: Colors.grey.shade300),
|
||||
borderRadius: BorderRadius.circular(
|
||||
SizeUtils.getByScreen(small: 12, big: 10),
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 11, big: 10),
|
||||
color: Colors.grey.shade500,
|
||||
),
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 4, big: 3)),
|
||||
Text(
|
||||
value,
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 22, big: 20),
|
||||
fontWeight: FontWeight.w700,
|
||||
color: color,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:sf_localizations/sf_localizations.dart';
|
||||
import 'package:utils/utils.dart';
|
||||
|
||||
class WeekDayRow extends StatelessWidget {
|
||||
final String week;
|
||||
final Color activeColor;
|
||||
final bool readOnly;
|
||||
final ValueChanged<int>? onToggle;
|
||||
|
||||
const WeekDayRow({
|
||||
super.key,
|
||||
required this.week,
|
||||
required this.activeColor,
|
||||
this.readOnly = true,
|
||||
this.onToggle,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final labels = [
|
||||
context.translate(I18n.weekdayMonShort),
|
||||
context.translate(I18n.weekdayTueShort),
|
||||
context.translate(I18n.weekdayWedShort),
|
||||
context.translate(I18n.weekdayThuShort),
|
||||
context.translate(I18n.weekdayFriShort),
|
||||
context.translate(I18n.weekdaySatShort),
|
||||
context.translate(I18n.weekdaySunShort),
|
||||
];
|
||||
final chars = week.padRight(7, '0').split('');
|
||||
final size = readOnly
|
||||
? SizeUtils.getByScreen<double>(small: 32, big: 28)
|
||||
: SizeUtils.getByScreen<double>(small: 40, big: 36);
|
||||
|
||||
return Row(
|
||||
mainAxisAlignment: readOnly
|
||||
? MainAxisAlignment.start
|
||||
: MainAxisAlignment.spaceBetween,
|
||||
children: List.generate(7, (index) {
|
||||
final active = chars[index] == '1';
|
||||
final child = Container(
|
||||
width: size,
|
||||
height: readOnly
|
||||
? SizeUtils.getByScreen<double>(small: 28, big: 24)
|
||||
: size,
|
||||
margin: readOnly
|
||||
? EdgeInsets.only(
|
||||
right: index < 6
|
||||
? SizeUtils.getByScreen<double>(small: 4, big: 3)
|
||||
: 0,
|
||||
)
|
||||
: null,
|
||||
decoration: BoxDecoration(
|
||||
color: active ? activeColor : Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
border: active ? null : Border.all(color: Colors.grey.shade300),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
labels[index],
|
||||
style: TextStyle(
|
||||
fontSize: readOnly
|
||||
? SizeUtils.getByScreen(small: 11, big: 10)
|
||||
: SizeUtils.getByScreen(small: 13, big: 12),
|
||||
fontWeight: FontWeight.w600,
|
||||
color: active ? Colors.white : Colors.grey.shade500,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
if (readOnly || onToggle == null) return child;
|
||||
return GestureDetector(onTap: () => onToggle!(index), child: child);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:sf_infrastructure/sf_infrastructure.dart';
|
||||
|
||||
import '../data/datasource/do_not_disturb_remote_datasource.dart';
|
||||
import '../data/datasource/do_not_disturb_remote_datasource_impl.dart';
|
||||
|
||||
final doNotDisturbRemoteDatasourceProvider =
|
||||
Provider<DoNotDisturbRemoteDatasource>(
|
||||
(_) => DoNotDisturbRemoteDatasourceImpl(GetIt.I<SaveFamilyRepository>()),
|
||||
);
|
||||
@@ -235,7 +235,7 @@ class _HeartRateFrequencySelector extends StatelessWidget {
|
||||
(opt) => Padding(
|
||||
padding: const EdgeInsets.only(left: 6),
|
||||
child: ChoiceChip(
|
||||
label: Text('${opt ~/ 60}m'),
|
||||
label: Text(formatSecondsCompact(opt)),
|
||||
selected: opt == currentFrequency,
|
||||
selectedColor: primaryColor,
|
||||
labelStyle: TextStyle(
|
||||
|
||||
@@ -16,6 +16,8 @@ class RemoteConnectionScreen extends ConsumerWidget {
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final theme = ref.watch(themePortProvider);
|
||||
final device = ref.watch(selectedDeviceProvider).value;
|
||||
final cameraEnabled = device?.capabilities?.camera?.enabled ?? false;
|
||||
|
||||
return LegacyPageLayout(
|
||||
theme: theme,
|
||||
@@ -28,21 +30,23 @@ class RemoteConnectionScreen extends ConsumerWidget {
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
_SectionButton(
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (_) => RemoteCameraScreen(
|
||||
navigationContract: navigationContract,
|
||||
if (cameraEnabled) ...[
|
||||
_SectionButton(
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (_) => RemoteCameraScreen(
|
||||
navigationContract: navigationContract,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
icon: Icons.photo_camera_outlined,
|
||||
text: I18n.remoteCamera,
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
);
|
||||
},
|
||||
icon: Icons.photo_camera_outlined,
|
||||
text: I18n.remoteCamera,
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
],
|
||||
_SectionButton(
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:location/src/features/location/presentation/state/location_map_view_model.dart';
|
||||
import 'package:utils/utils.dart';
|
||||
import 'map_action_button.dart';
|
||||
|
||||
class MapActionsPanel extends StatelessWidget {
|
||||
@@ -95,10 +96,7 @@ class FrequencySelector extends ConsumerWidget {
|
||||
required this.onChanged,
|
||||
});
|
||||
|
||||
String _formatSeconds(int seconds) {
|
||||
if (seconds >= 60) return '${seconds ~/ 60}m';
|
||||
return '${seconds}s';
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
@@ -149,7 +147,7 @@ class FrequencySelector extends ConsumerWidget {
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
_formatSeconds(opt),
|
||||
formatSecondsCompact(opt),
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
|
||||
@@ -70,6 +70,7 @@ class AppRoutes {
|
||||
static const activityMeter = '$deviceManagement/activity_meter';
|
||||
static const appsUse = '$deviceManagement/apps_use';
|
||||
static const volumeControl = '$deviceManagement/volume_control';
|
||||
static const doNotDisturb = '$deviceManagement/do_not_disturb';
|
||||
static const callHistory = '$deviceManagement/call_history';
|
||||
static const backgroundImage = '$deviceManagement/background_image';
|
||||
|
||||
|
||||
@@ -668,7 +668,8 @@
|
||||
"errorActivityData": "Aktivitätsdaten konnten nicht geladen werden",
|
||||
"errorPedometer": "Der Schrittzähler konnte nicht aktualisiert werden",
|
||||
"errorContactsMin": "Das Gerät muss mindestens einen Kontakt haben",
|
||||
"errorContactsMax": "Das Gerät kann nicht mehr als 10 Kontakte haben",
|
||||
"errorContactsMax": "Maximale Kontaktanzahl für dieses Gerät erreicht",
|
||||
"errorSosContactsMax": "Maximale SOS-Kontaktanzahl für dieses Gerät erreicht",
|
||||
"customBackground": "Benutzerdefiniertes Hintergrundbild",
|
||||
"backgroundImageDescription": "Legen Sie ein Foto als benutzerdefinierten Bildschirmschoner für das Gerät fest",
|
||||
"backgroundImageTapToSelect": "Tippen Sie, um ein Foto auszuwählen",
|
||||
@@ -773,6 +774,29 @@
|
||||
"deviceSettings": "Einstellungen",
|
||||
"disableFunctions": "Funktionen deaktivieren",
|
||||
"doNotDisturb": "Nicht stören",
|
||||
"doNotDisturbDescription": "Wenn aktiviert, werden alle Benachrichtigungen, Anrufe und Alarme auf der Uhr stummgeschaltet. Nur Anrufe von SOS-Kontakten werden zugelassen.",
|
||||
"doNotDisturbStatusOn": "Aktiviert",
|
||||
"doNotDisturbStatusOff": "Deaktiviert",
|
||||
"doNotDisturbEnabled": "Nicht stören aktiviert",
|
||||
"doNotDisturbDisabled": "Nicht stören deaktiviert",
|
||||
"doNotDisturbError": "Fehler beim Ändern des Nicht-stören-Modus",
|
||||
"doNotDisturbEmpty": "Keine Zeiträume konfiguriert",
|
||||
"doNotDisturbAddPeriod": "Zeitraum hinzufügen",
|
||||
"doNotDisturbEditPeriod": "Zeitraum bearbeiten",
|
||||
"doNotDisturbMaxPeriods": "Maximal {max} Zeiträume erlaubt",
|
||||
"doNotDisturbSave": "Änderungen speichern",
|
||||
"doNotDisturbSaved": "Zeiträume gespeichert",
|
||||
"doNotDisturbConfirm": "Bestätigen",
|
||||
"doNotDisturbStart": "Beginn",
|
||||
"doNotDisturbEnd": "Ende",
|
||||
"doNotDisturbDays": "Wochentage",
|
||||
"weekdayMonShort": "M",
|
||||
"weekdayTueShort": "D",
|
||||
"weekdayWedShort": "M",
|
||||
"weekdayThuShort": "D",
|
||||
"weekdayFriShort": "F",
|
||||
"weekdaySatShort": "S",
|
||||
"weekdaySunShort": "S",
|
||||
"editDeviceTitle": "Gerät bearbeiten",
|
||||
"enterEmail": "Geben Sie Ihre E-Mail ein",
|
||||
"enterMessage": "Ihre Nachricht",
|
||||
|
||||
@@ -531,6 +531,29 @@
|
||||
"activityScheduleTitle": "Calendar",
|
||||
"contactsAgendaTitle": "Contacts",
|
||||
"doNotDisturb": "Do not disturb",
|
||||
"doNotDisturbDescription": "When enabled, the watch will silence all notifications, calls, and alerts. Only SOS contacts calls will be allowed.",
|
||||
"doNotDisturbStatusOn": "Enabled",
|
||||
"doNotDisturbStatusOff": "Disabled",
|
||||
"doNotDisturbEnabled": "Do not disturb enabled",
|
||||
"doNotDisturbDisabled": "Do not disturb disabled",
|
||||
"doNotDisturbError": "Error changing do not disturb mode",
|
||||
"doNotDisturbEmpty": "No periods configured",
|
||||
"doNotDisturbAddPeriod": "Add period",
|
||||
"doNotDisturbEditPeriod": "Edit period",
|
||||
"doNotDisturbMaxPeriods": "Maximum {max} periods allowed",
|
||||
"doNotDisturbSave": "Save changes",
|
||||
"doNotDisturbSaved": "Periods saved successfully",
|
||||
"doNotDisturbConfirm": "Confirm",
|
||||
"doNotDisturbStart": "Start",
|
||||
"doNotDisturbEnd": "End",
|
||||
"doNotDisturbDays": "Days of the week",
|
||||
"weekdayMonShort": "M",
|
||||
"weekdayTueShort": "T",
|
||||
"weekdayWedShort": "W",
|
||||
"weekdayThuShort": "T",
|
||||
"weekdayFriShort": "F",
|
||||
"weekdaySatShort": "S",
|
||||
"weekdaySunShort": "S",
|
||||
"videoCall": "Video call",
|
||||
"healthTitle": "Health",
|
||||
"healthEmpty": "No health data",
|
||||
@@ -797,7 +820,8 @@
|
||||
"errorActivityData": "Could not load activity data",
|
||||
"errorPedometer": "Could not update pedometer",
|
||||
"errorContactsMin": "The device must have at least one contact",
|
||||
"errorContactsMax": "The device cannot have more than 10 contacts",
|
||||
"errorContactsMax": "Maximum contacts reached for this device",
|
||||
"errorSosContactsMax": "Maximum SOS contacts reached for this device",
|
||||
"customBackground": "Custom background image",
|
||||
"backgroundImageDescription": "Set a photo as a custom screensaver for the device",
|
||||
"backgroundImageTapToSelect": "Tap to select a photo",
|
||||
|
||||
@@ -532,6 +532,29 @@
|
||||
"activityScheduleTitle": "Horario de actividades",
|
||||
"contactsAgendaTitle": "Agenda",
|
||||
"doNotDisturb": "No molestar",
|
||||
"doNotDisturbDescription": "Cuando está activado, el reloj silenciará todas las notificaciones, llamadas y alertas. Solo se permitirán llamadas de contactos SOS.",
|
||||
"doNotDisturbStatusOn": "Activado",
|
||||
"doNotDisturbStatusOff": "Desactivado",
|
||||
"doNotDisturbEnabled": "No molestar activado",
|
||||
"doNotDisturbDisabled": "No molestar desactivado",
|
||||
"doNotDisturbError": "Error al cambiar modo no molestar",
|
||||
"doNotDisturbEmpty": "Sin periodos configurados",
|
||||
"doNotDisturbAddPeriod": "Añadir periodo",
|
||||
"doNotDisturbEditPeriod": "Editar periodo",
|
||||
"doNotDisturbMaxPeriods": "Máximo {max} periodos permitidos",
|
||||
"doNotDisturbSave": "Guardar cambios",
|
||||
"doNotDisturbSaved": "Periodos guardados correctamente",
|
||||
"doNotDisturbConfirm": "Confirmar",
|
||||
"doNotDisturbStart": "Inicio",
|
||||
"doNotDisturbEnd": "Fin",
|
||||
"doNotDisturbDays": "Días de la semana",
|
||||
"weekdayMonShort": "L",
|
||||
"weekdayTueShort": "M",
|
||||
"weekdayWedShort": "X",
|
||||
"weekdayThuShort": "J",
|
||||
"weekdayFriShort": "V",
|
||||
"weekdaySatShort": "S",
|
||||
"weekdaySunShort": "D",
|
||||
"videoCall": "Video llamada",
|
||||
"healthTitle": "Salud",
|
||||
"healthEmpty": "Sin datos de salud",
|
||||
@@ -798,7 +821,8 @@
|
||||
"errorActivityData": "No se pudieron cargar los datos de actividad",
|
||||
"errorPedometer": "No se pudo actualizar el podómetro",
|
||||
"errorContactsMin": "El dispositivo debe tener al menos un contacto",
|
||||
"errorContactsMax": "El dispositivo no puede tener más de 10 contactos",
|
||||
"errorContactsMax": "Se ha alcanzado el máximo de contactos para este dispositivo",
|
||||
"errorSosContactsMax": "Se ha alcanzado el máximo de contactos SOS para este dispositivo",
|
||||
"customBackground": "Fondo de pantalla personalizado",
|
||||
"backgroundImageDescription": "Configura una foto como protector de pantalla exclusivo para el dispositivo",
|
||||
"backgroundImageTapToSelect": "Pulsa para seleccionar una foto",
|
||||
|
||||
@@ -668,7 +668,8 @@
|
||||
"errorActivityData": "Impossible de charger les données d'activité",
|
||||
"errorPedometer": "Impossible de mettre à jour le podomètre",
|
||||
"errorContactsMin": "L'appareil doit avoir au moins un contact",
|
||||
"errorContactsMax": "L'appareil ne peut pas avoir plus de 10 contacts",
|
||||
"errorContactsMax": "Nombre maximum de contacts atteint pour cet appareil",
|
||||
"errorSosContactsMax": "Nombre maximum de contacts SOS atteint pour cet appareil",
|
||||
"customBackground": "Image de fond personnalisée",
|
||||
"backgroundImageDescription": "Définissez une photo comme écran de veille personnalisé pour l'appareil",
|
||||
"backgroundImageTapToSelect": "Appuyez pour sélectionner une photo",
|
||||
@@ -773,6 +774,29 @@
|
||||
"deviceSettings": "Paramètres",
|
||||
"disableFunctions": "Désactiver les fonctions",
|
||||
"doNotDisturb": "Ne pas déranger",
|
||||
"doNotDisturbDescription": "Lorsqu'il est activé, la montre désactivera toutes les notifications, appels et alertes. Seuls les appels des contacts SOS seront autorisés.",
|
||||
"doNotDisturbStatusOn": "Activé",
|
||||
"doNotDisturbStatusOff": "Désactivé",
|
||||
"doNotDisturbEnabled": "Ne pas déranger activé",
|
||||
"doNotDisturbDisabled": "Ne pas déranger désactivé",
|
||||
"doNotDisturbError": "Erreur lors du changement du mode ne pas déranger",
|
||||
"doNotDisturbEmpty": "Aucune période configurée",
|
||||
"doNotDisturbAddPeriod": "Ajouter une période",
|
||||
"doNotDisturbEditPeriod": "Modifier la période",
|
||||
"doNotDisturbMaxPeriods": "Maximum {max} périodes autorisées",
|
||||
"doNotDisturbSave": "Enregistrer",
|
||||
"doNotDisturbSaved": "Périodes enregistrées",
|
||||
"doNotDisturbConfirm": "Confirmer",
|
||||
"doNotDisturbStart": "Début",
|
||||
"doNotDisturbEnd": "Fin",
|
||||
"doNotDisturbDays": "Jours de la semaine",
|
||||
"weekdayMonShort": "L",
|
||||
"weekdayTueShort": "M",
|
||||
"weekdayWedShort": "M",
|
||||
"weekdayThuShort": "J",
|
||||
"weekdayFriShort": "V",
|
||||
"weekdaySatShort": "S",
|
||||
"weekdaySunShort": "D",
|
||||
"editDeviceTitle": "Modifier l'appareil",
|
||||
"enterEmail": "Entrez votre e-mail",
|
||||
"enterMessage": "Votre message",
|
||||
|
||||
@@ -668,7 +668,8 @@
|
||||
"errorActivityData": "Impossibile caricare i dati di attività",
|
||||
"errorPedometer": "Impossibile aggiornare il contapassi",
|
||||
"errorContactsMin": "Il dispositivo deve avere almeno un contatto",
|
||||
"errorContactsMax": "Il dispositivo non può avere più di 10 contatti",
|
||||
"errorContactsMax": "Numero massimo di contatti raggiunto per questo dispositivo",
|
||||
"errorSosContactsMax": "Numero massimo di contatti SOS raggiunto per questo dispositivo",
|
||||
"customBackground": "Immagine di sfondo personalizzata",
|
||||
"backgroundImageDescription": "Imposta una foto come screensaver personalizzato per il dispositivo",
|
||||
"backgroundImageTapToSelect": "Tocca per selezionare una foto",
|
||||
@@ -773,6 +774,29 @@
|
||||
"deviceSettings": "Impostazioni",
|
||||
"disableFunctions": "Disattiva funzioni",
|
||||
"doNotDisturb": "Non disturbare",
|
||||
"doNotDisturbDescription": "Quando attivato, l'orologio disattiverà tutte le notifiche, chiamate e avvisi. Saranno consentite solo le chiamate dai contatti SOS.",
|
||||
"doNotDisturbStatusOn": "Attivato",
|
||||
"doNotDisturbStatusOff": "Disattivato",
|
||||
"doNotDisturbEnabled": "Non disturbare attivato",
|
||||
"doNotDisturbDisabled": "Non disturbare disattivato",
|
||||
"doNotDisturbError": "Errore nel cambiare la modalità non disturbare",
|
||||
"doNotDisturbEmpty": "Nessun periodo configurato",
|
||||
"doNotDisturbAddPeriod": "Aggiungi periodo",
|
||||
"doNotDisturbEditPeriod": "Modifica periodo",
|
||||
"doNotDisturbMaxPeriods": "Massimo {max} periodi consentiti",
|
||||
"doNotDisturbSave": "Salva modifiche",
|
||||
"doNotDisturbSaved": "Periodi salvati",
|
||||
"doNotDisturbConfirm": "Conferma",
|
||||
"doNotDisturbStart": "Inizio",
|
||||
"doNotDisturbEnd": "Fine",
|
||||
"doNotDisturbDays": "Giorni della settimana",
|
||||
"weekdayMonShort": "L",
|
||||
"weekdayTueShort": "M",
|
||||
"weekdayWedShort": "M",
|
||||
"weekdayThuShort": "G",
|
||||
"weekdayFriShort": "V",
|
||||
"weekdaySatShort": "S",
|
||||
"weekdaySunShort": "D",
|
||||
"editDeviceTitle": "Modifica dispositivo",
|
||||
"enterEmail": "Inserisci la tua email",
|
||||
"enterMessage": "Il tuo messaggio",
|
||||
|
||||
@@ -668,7 +668,8 @@
|
||||
"errorActivityData": "Não foi possível carregar os dados de atividade",
|
||||
"errorPedometer": "Não foi possível atualizar o pedómetro",
|
||||
"errorContactsMin": "O dispositivo deve ter pelo menos um contacto",
|
||||
"errorContactsMax": "O dispositivo não pode ter mais de 10 contactos",
|
||||
"errorContactsMax": "Número máximo de contactos atingido para este dispositivo",
|
||||
"errorSosContactsMax": "Número máximo de contactos SOS atingido para este dispositivo",
|
||||
"customBackground": "Imagem de fundo personalizada",
|
||||
"backgroundImageDescription": "Defina uma foto como protetor de ecrã personalizado para o dispositivo",
|
||||
"backgroundImageTapToSelect": "Toque para selecionar uma foto",
|
||||
@@ -773,6 +774,29 @@
|
||||
"deviceSettings": "Configurações",
|
||||
"disableFunctions": "Desativar funções",
|
||||
"doNotDisturb": "Não perturbe",
|
||||
"doNotDisturbDescription": "Quando ativado, o relógio silenciará todas as notificações, chamadas e alertas. Apenas chamadas de contactos SOS serão permitidas.",
|
||||
"doNotDisturbStatusOn": "Ativado",
|
||||
"doNotDisturbStatusOff": "Desativado",
|
||||
"doNotDisturbEnabled": "Não perturbe ativado",
|
||||
"doNotDisturbDisabled": "Não perturbe desativado",
|
||||
"doNotDisturbError": "Erro ao alterar o modo não perturbe",
|
||||
"doNotDisturbEmpty": "Sem períodos configurados",
|
||||
"doNotDisturbAddPeriod": "Adicionar período",
|
||||
"doNotDisturbEditPeriod": "Editar período",
|
||||
"doNotDisturbMaxPeriods": "Máximo {max} períodos permitidos",
|
||||
"doNotDisturbSave": "Guardar alterações",
|
||||
"doNotDisturbSaved": "Períodos guardados",
|
||||
"doNotDisturbConfirm": "Confirmar",
|
||||
"doNotDisturbStart": "Início",
|
||||
"doNotDisturbEnd": "Fim",
|
||||
"doNotDisturbDays": "Dias da semana",
|
||||
"weekdayMonShort": "S",
|
||||
"weekdayTueShort": "T",
|
||||
"weekdayWedShort": "Q",
|
||||
"weekdayThuShort": "Q",
|
||||
"weekdayFriShort": "S",
|
||||
"weekdaySatShort": "S",
|
||||
"weekdaySunShort": "D",
|
||||
"editDeviceTitle": "Editar dispositivo",
|
||||
"enterEmail": "Insira seu e-mail",
|
||||
"enterMessage": "Sua mensagem",
|
||||
|
||||
@@ -317,6 +317,29 @@ class I18n {
|
||||
static const String documentTypeNie = 'documentTypeNie';
|
||||
static const String documentTypePassport = 'documentTypePassport';
|
||||
static const String doNotDisturb = 'doNotDisturb';
|
||||
static const String doNotDisturbDescription = 'doNotDisturbDescription';
|
||||
static const String doNotDisturbStatusOn = 'doNotDisturbStatusOn';
|
||||
static const String doNotDisturbStatusOff = 'doNotDisturbStatusOff';
|
||||
static const String doNotDisturbEnabled = 'doNotDisturbEnabled';
|
||||
static const String doNotDisturbDisabled = 'doNotDisturbDisabled';
|
||||
static const String doNotDisturbError = 'doNotDisturbError';
|
||||
static const String doNotDisturbEmpty = 'doNotDisturbEmpty';
|
||||
static const String doNotDisturbAddPeriod = 'doNotDisturbAddPeriod';
|
||||
static const String doNotDisturbEditPeriod = 'doNotDisturbEditPeriod';
|
||||
static const String doNotDisturbMaxPeriods = 'doNotDisturbMaxPeriods';
|
||||
static const String doNotDisturbSave = 'doNotDisturbSave';
|
||||
static const String doNotDisturbSaved = 'doNotDisturbSaved';
|
||||
static const String doNotDisturbConfirm = 'doNotDisturbConfirm';
|
||||
static const String doNotDisturbStart = 'doNotDisturbStart';
|
||||
static const String doNotDisturbEnd = 'doNotDisturbEnd';
|
||||
static const String doNotDisturbDays = 'doNotDisturbDays';
|
||||
static const String weekdayMonShort = 'weekdayMonShort';
|
||||
static const String weekdayTueShort = 'weekdayTueShort';
|
||||
static const String weekdayWedShort = 'weekdayWedShort';
|
||||
static const String weekdayThuShort = 'weekdayThuShort';
|
||||
static const String weekdayFriShort = 'weekdayFriShort';
|
||||
static const String weekdaySatShort = 'weekdaySatShort';
|
||||
static const String weekdaySunShort = 'weekdaySunShort';
|
||||
static const String dontHaveAccount = 'dontHaveAccount';
|
||||
static const String download = 'download';
|
||||
static const String editAlarm = 'editAlarm';
|
||||
@@ -350,6 +373,7 @@ class I18n {
|
||||
static const String errorBirthDateRequired = 'errorBirthDateRequired';
|
||||
static const String errorCall = 'errorCall';
|
||||
static const String errorContactsMax = 'errorContactsMax';
|
||||
static const String errorSosContactsMax = 'errorSosContactsMax';
|
||||
static const String errorContactsMin = 'errorContactsMin';
|
||||
static const String errorDisableFunctions = 'errorDisableFunctions';
|
||||
static const String errorDocumentNumberRequired =
|
||||
|
||||
@@ -18,6 +18,13 @@ abstract class DeviceCapabilitiesModel with _$DeviceCapabilitiesModel {
|
||||
DeviceCapabilityTakepillsModel? takepills,
|
||||
DeviceCapabilityOptionModel? location,
|
||||
DeviceCapabilityCameraModel? camera,
|
||||
DeviceCapabilityDoNotDisturbModel? doNotDisturbs,
|
||||
DeviceCapabilityAlarmsModel? alarms,
|
||||
DeviceCapabilityAppUsageModel? appUsageSchedules,
|
||||
DeviceCapabilityEnabledModel? keyboard,
|
||||
DeviceCapabilityEnabledModel? nightMode,
|
||||
DeviceCapabilityEnabledModel? wifi,
|
||||
DeviceCapabilityEnabledModel? deviceBackground,
|
||||
}) = _DeviceCapabilitiesModel;
|
||||
|
||||
factory DeviceCapabilitiesModel.fromJson(Map<String, dynamic> json) =>
|
||||
@@ -131,6 +138,39 @@ abstract class DeviceCapabilityCameraModel with _$DeviceCapabilityCameraModel {
|
||||
_$DeviceCapabilityCameraModelFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class DeviceCapabilityDoNotDisturbModel with _$DeviceCapabilityDoNotDisturbModel {
|
||||
const factory DeviceCapabilityDoNotDisturbModel({
|
||||
@Default(4) int maxPeriods,
|
||||
}) = _DeviceCapabilityDoNotDisturbModel;
|
||||
|
||||
factory DeviceCapabilityDoNotDisturbModel.fromJson(Map<String, dynamic> json) =>
|
||||
_$DeviceCapabilityDoNotDisturbModelFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class DeviceCapabilityAlarmsModel
|
||||
with _$DeviceCapabilityAlarmsModel {
|
||||
const factory DeviceCapabilityAlarmsModel({
|
||||
@Default(false) bool enabled,
|
||||
@Default(3) int maxAlarms,
|
||||
}) = _DeviceCapabilityAlarmsModel;
|
||||
|
||||
factory DeviceCapabilityAlarmsModel.fromJson(Map<String, dynamic> json) =>
|
||||
_$DeviceCapabilityAlarmsModelFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class DeviceCapabilityAppUsageModel
|
||||
with _$DeviceCapabilityAppUsageModel {
|
||||
const factory DeviceCapabilityAppUsageModel({
|
||||
@Default(3) int maxPeriods,
|
||||
}) = _DeviceCapabilityAppUsageModel;
|
||||
|
||||
factory DeviceCapabilityAppUsageModel.fromJson(Map<String, dynamic> json) =>
|
||||
_$DeviceCapabilityAppUsageModelFromJson(json);
|
||||
}
|
||||
|
||||
extension DeviceCapabilitiesModelMapper on DeviceCapabilitiesModel {
|
||||
DeviceCapabilitiesEntity toEntity() => DeviceCapabilitiesEntity(
|
||||
heartbeats: heartbeats != null
|
||||
@@ -198,5 +238,31 @@ extension DeviceCapabilitiesModelMapper on DeviceCapabilitiesModel {
|
||||
enabled: camera!.enabled,
|
||||
)
|
||||
: null,
|
||||
doNotDisturbs: doNotDisturbs != null
|
||||
? DeviceCapabilityDoNotDisturbEntity(maxPeriods: doNotDisturbs!.maxPeriods)
|
||||
: null,
|
||||
alarms: alarms != null
|
||||
? DeviceCapabilityAlarmsEntity(
|
||||
enabled: alarms!.enabled,
|
||||
maxAlarms: alarms!.maxAlarms,
|
||||
)
|
||||
: null,
|
||||
appUsageSchedules: appUsageSchedules != null
|
||||
? DeviceCapabilityAppUsageEntity(
|
||||
maxPeriods: appUsageSchedules!.maxPeriods,
|
||||
)
|
||||
: null,
|
||||
keyboard: keyboard != null
|
||||
? DeviceCapabilityEnabledEntity(enabled: keyboard!.enabled)
|
||||
: null,
|
||||
nightMode: nightMode != null
|
||||
? DeviceCapabilityEnabledEntity(enabled: nightMode!.enabled)
|
||||
: null,
|
||||
wifi: wifi != null
|
||||
? DeviceCapabilityEnabledEntity(enabled: wifi!.enabled)
|
||||
: null,
|
||||
deviceBackground: deviceBackground != null
|
||||
? DeviceCapabilityEnabledEntity(enabled: deviceBackground!.enabled)
|
||||
: null,
|
||||
);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -59,6 +59,41 @@ _DeviceCapabilitiesModel _$DeviceCapabilitiesModelFromJson(
|
||||
: DeviceCapabilityCameraModel.fromJson(
|
||||
json['camera'] as Map<String, dynamic>,
|
||||
),
|
||||
doNotDisturbs: json['doNotDisturbs'] == null
|
||||
? null
|
||||
: DeviceCapabilityDoNotDisturbModel.fromJson(
|
||||
json['doNotDisturbs'] as Map<String, dynamic>,
|
||||
),
|
||||
alarms: json['alarms'] == null
|
||||
? null
|
||||
: DeviceCapabilityAlarmsModel.fromJson(
|
||||
json['alarms'] as Map<String, dynamic>,
|
||||
),
|
||||
appUsageSchedules: json['appUsageSchedules'] == null
|
||||
? null
|
||||
: DeviceCapabilityAppUsageModel.fromJson(
|
||||
json['appUsageSchedules'] as Map<String, dynamic>,
|
||||
),
|
||||
keyboard: json['keyboard'] == null
|
||||
? null
|
||||
: DeviceCapabilityEnabledModel.fromJson(
|
||||
json['keyboard'] as Map<String, dynamic>,
|
||||
),
|
||||
nightMode: json['nightMode'] == null
|
||||
? null
|
||||
: DeviceCapabilityEnabledModel.fromJson(
|
||||
json['nightMode'] as Map<String, dynamic>,
|
||||
),
|
||||
wifi: json['wifi'] == null
|
||||
? null
|
||||
: DeviceCapabilityEnabledModel.fromJson(
|
||||
json['wifi'] as Map<String, dynamic>,
|
||||
),
|
||||
deviceBackground: json['deviceBackground'] == null
|
||||
? null
|
||||
: DeviceCapabilityEnabledModel.fromJson(
|
||||
json['deviceBackground'] as Map<String, dynamic>,
|
||||
),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$DeviceCapabilitiesModelToJson(
|
||||
@@ -74,6 +109,13 @@ Map<String, dynamic> _$DeviceCapabilitiesModelToJson(
|
||||
'takepills': instance.takepills,
|
||||
'location': instance.location,
|
||||
'camera': instance.camera,
|
||||
'doNotDisturbs': instance.doNotDisturbs,
|
||||
'alarms': instance.alarms,
|
||||
'appUsageSchedules': instance.appUsageSchedules,
|
||||
'keyboard': instance.keyboard,
|
||||
'nightMode': instance.nightMode,
|
||||
'wifi': instance.wifi,
|
||||
'deviceBackground': instance.deviceBackground,
|
||||
};
|
||||
|
||||
_DeviceCapabilityEnabledModel _$DeviceCapabilityEnabledModelFromJson(
|
||||
@@ -209,3 +251,37 @@ _DeviceCapabilityCameraModel _$DeviceCapabilityCameraModelFromJson(
|
||||
Map<String, dynamic> _$DeviceCapabilityCameraModelToJson(
|
||||
_DeviceCapabilityCameraModel instance,
|
||||
) => <String, dynamic>{'format': instance.format, 'enabled': instance.enabled};
|
||||
|
||||
_DeviceCapabilityDoNotDisturbModel _$DeviceCapabilityDoNotDisturbModelFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _DeviceCapabilityDoNotDisturbModel(
|
||||
maxPeriods: (json['maxPeriods'] as num?)?.toInt() ?? 4,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$DeviceCapabilityDoNotDisturbModelToJson(
|
||||
_DeviceCapabilityDoNotDisturbModel instance,
|
||||
) => <String, dynamic>{'maxPeriods': instance.maxPeriods};
|
||||
|
||||
_DeviceCapabilityAlarmsModel _$DeviceCapabilityAlarmsModelFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _DeviceCapabilityAlarmsModel(
|
||||
enabled: json['enabled'] as bool? ?? false,
|
||||
maxAlarms: (json['maxAlarms'] as num?)?.toInt() ?? 3,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$DeviceCapabilityAlarmsModelToJson(
|
||||
_DeviceCapabilityAlarmsModel instance,
|
||||
) => <String, dynamic>{
|
||||
'enabled': instance.enabled,
|
||||
'maxAlarms': instance.maxAlarms,
|
||||
};
|
||||
|
||||
_DeviceCapabilityAppUsageModel _$DeviceCapabilityAppUsageModelFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _DeviceCapabilityAppUsageModel(
|
||||
maxPeriods: (json['maxPeriods'] as num?)?.toInt() ?? 3,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$DeviceCapabilityAppUsageModelToJson(
|
||||
_DeviceCapabilityAppUsageModel instance,
|
||||
) => <String, dynamic>{'maxPeriods': instance.maxPeriods};
|
||||
|
||||
@@ -15,6 +15,13 @@ abstract class DeviceCapabilitiesEntity with _$DeviceCapabilitiesEntity {
|
||||
DeviceCapabilityTakepillsEntity? takepills,
|
||||
DeviceCapabilityOptionEntity? location,
|
||||
DeviceCapabilityCameraEntity? camera,
|
||||
DeviceCapabilityDoNotDisturbEntity? doNotDisturbs,
|
||||
DeviceCapabilityAlarmsEntity? alarms,
|
||||
DeviceCapabilityAppUsageEntity? appUsageSchedules,
|
||||
DeviceCapabilityEnabledEntity? keyboard,
|
||||
DeviceCapabilityEnabledEntity? nightMode,
|
||||
DeviceCapabilityEnabledEntity? wifi,
|
||||
DeviceCapabilityEnabledEntity? deviceBackground,
|
||||
}) = _DeviceCapabilitiesEntity;
|
||||
}
|
||||
|
||||
@@ -63,6 +70,11 @@ abstract class DeviceCapabilityContactTypeEntity
|
||||
}) = _DeviceCapabilityContactTypeEntity;
|
||||
}
|
||||
|
||||
extension DeviceCapabilityContactsX on DeviceCapabilityContactsEntity {
|
||||
int maxForType(String type, {int fallback = 10}) =>
|
||||
types.where((t) => t.type == type).firstOrNull?.amount ?? fallback;
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class DeviceCapabilitySettingsEntity
|
||||
with _$DeviceCapabilitySettingsEntity {
|
||||
@@ -99,3 +111,27 @@ abstract class DeviceCapabilityCameraEntity
|
||||
@Default(false) bool enabled,
|
||||
}) = _DeviceCapabilityCameraEntity;
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class DeviceCapabilityDoNotDisturbEntity with _$DeviceCapabilityDoNotDisturbEntity {
|
||||
const factory DeviceCapabilityDoNotDisturbEntity({
|
||||
@Default(4) int maxPeriods,
|
||||
}) = _DeviceCapabilityDoNotDisturbEntity;
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class DeviceCapabilityAlarmsEntity
|
||||
with _$DeviceCapabilityAlarmsEntity {
|
||||
const factory DeviceCapabilityAlarmsEntity({
|
||||
@Default(false) bool enabled,
|
||||
@Default(3) int maxAlarms,
|
||||
}) = _DeviceCapabilityAlarmsEntity;
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class DeviceCapabilityAppUsageEntity
|
||||
with _$DeviceCapabilityAppUsageEntity {
|
||||
const factory DeviceCapabilityAppUsageEntity({
|
||||
@Default(3) int maxPeriods,
|
||||
}) = _DeviceCapabilityAppUsageEntity;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -34,6 +34,11 @@ mixin DeviceTracking on Tracking {
|
||||
'level': level,
|
||||
});
|
||||
|
||||
Future<void> legacyDeviceDoNotDisturbScheduleSaved(int periodsCount) =>
|
||||
trackEvent('${_prefix}_do_not_disturb_schedule_saved', {
|
||||
'periods_count': periodsCount,
|
||||
});
|
||||
|
||||
Future<void> legacyDeviceBackgroundImageChanged() =>
|
||||
trackEvent('${_prefix}_background_image_changed');
|
||||
|
||||
|
||||
5
packages/utils/lib/src/duration_format.dart
Normal file
5
packages/utils/lib/src/duration_format.dart
Normal file
@@ -0,0 +1,5 @@
|
||||
String formatSecondsCompact(int seconds) {
|
||||
if (seconds >= 3600) return '${seconds ~/ 3600}h';
|
||||
if (seconds >= 60) return '${seconds ~/ 60}m';
|
||||
return '${seconds}s';
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
export 'src/date_utils.dart';
|
||||
export 'src/duration_format.dart';
|
||||
export 'src/size_utils.dart';
|
||||
export 'src/test.dart';
|
||||
|
||||
Reference in New Issue
Block a user