Compare commits

...

3 Commits

Author SHA1 Message Date
6a29c75630 Merge remote-tracking branch 'origin/fusion-app' into feature/contacts
# Conflicts:
#	packages/sf_localizations/assets/l10n/en.json
#	packages/sf_localizations/assets/l10n/es.json
#	packages/sf_localizations/lib/src/generated/i18n.dart
2026-03-26 19:11:03 +01:00
429b67a536 Merge branch 'refs/heads/fusion-app' into feature/contacts
# Conflicts:
#	modules/legacy/packages/legacy_shared/lib/legacy_shared.dart
#	packages/sf_localizations/assets/l10n/en.json
#	packages/sf_localizations/assets/l10n/es.json
#	packages/sf_localizations/lib/src/generated/i18n.dart
2026-03-25 09:22:11 +01:00
75df4736e2 change block phones behaviour 2026-03-24 13:43:26 +01:00
16 changed files with 365 additions and 186 deletions

View File

@@ -2,7 +2,6 @@ import 'package:dio/dio.dart';
import 'package:legacy_shared/legacy_shared.dart';
import 'package:sf_infrastructure/sf_infrastructure.dart';
import 'call_history_entity.dart';
import 'call_history_response_model.dart';
class CallHistoryDatasource {

View File

@@ -4,7 +4,6 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:legacy_shared/legacy_shared.dart';
import 'package:sf_localizations/sf_localizations.dart';
import '../data/call_history_entity.dart';
import 'state/call_history_view_model.dart';
import 'state/call_history_view_state.dart';

View File

@@ -3,7 +3,6 @@ import 'package:legacy_shared/legacy_shared.dart';
import '../../data/call_history_datasource.dart';
import '../../data/call_history_datasource_provider.dart';
import '../../data/call_history_entity.dart';
import 'call_history_view_state.dart';
final callHistoryViewModelProvider =

View File

@@ -1,6 +1,5 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import '../../data/call_history_entity.dart';
import 'package:legacy_shared/legacy_shared.dart';
part 'call_history_view_state.freezed.dart';

View File

@@ -1,7 +1,9 @@
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:navigation/navigation.dart';
import 'package:settings/src/features/block_phone/presentation/blocked_calls_screen.dart';
import 'package:sf_localizations/sf_localizations.dart';
import 'package:utils/utils.dart';
@@ -75,186 +77,120 @@ class BlockPhoneScreen extends ConsumerWidget {
color: primaryColor,
),
),
actions: [
Padding(
padding: EdgeInsets.only(
right: SizeUtils.getByScreen(small: 16, big: 14),
),
child: DecoratedBox(
decoration: BoxDecoration(
color: primaryColor,
shape: BoxShape.circle,
),
child: IconButton(
onPressed: () => showAddContactSheet(context),
icon: Icon(
Icons.add,
color: Colors.white,
size: SizeUtils.getByScreen(small: 24, big: 22),
),
),
),
),
],
),
body: SafeArea(
top: false,
child: state.isLoading
? const Center(child: CircularProgressIndicator())
: state.contacts.isEmpty
? _EmptyState(primaryColor: primaryColor)
: _ContactList(),
: Padding(
padding: EdgeInsets.symmetric(horizontal: 14),
child: Column(
children: [
const _AllowContactsSection(),
SizedBox(height: 10),
const _BlockedCallsSection()
],
)
)
),
);
}
}
class _EmptyState extends StatelessWidget {
final Color primaryColor;
class _AllowContactsSection extends ConsumerWidget {
const _EmptyState({required this.primaryColor});
@override
Widget build(BuildContext context) {
return Center(
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: SizeUtils.getByScreen(small: 32, big: 30),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
Icons.phone_locked_outlined,
color: primaryColor,
size: SizeUtils.getByScreen(small: 120, big: 140),
),
SizedBox(height: SizeUtils.getByScreen(small: 20, big: 24)),
Text(
context.translate(I18n.noBlockedNumbers),
style: TextStyle(
fontSize: SizeUtils.getByScreen(small: 16, big: 17),
fontWeight: FontWeight.w500,
color: Colors.grey,
),
),
SizedBox(height: SizeUtils.getByScreen(small: 8, big: 10)),
Text(
context.translate(I18n.noBlockedNumbersDescription),
textAlign: TextAlign.center,
style: TextStyle(
fontSize: SizeUtils.getByScreen(small: 14, big: 15),
color: Colors.grey,
),
),
],
),
),
);
}
}
class _ContactList extends ConsumerWidget {
const _ContactList();
const _AllowContactsSection();
@override
Widget build(BuildContext context, WidgetRef ref) {
final theme = ref.watch(themePortProvider);
final contacts = ref.watch(
blockPhoneViewModelProvider.select((s) => s.contacts),
final theme = ref.read(themePortProvider);
final vm = ref.read(blockPhoneViewModelProvider.notifier);
final allowContacts = ref.watch(
blockPhoneViewModelProvider.select((s)=>s.allowContacts)
);
final primaryColor = theme.getColorFor(ThemeCode.legacyPrimary);
return SingleChildScrollView(
child: Padding(
padding: SizeUtils.getByScreen(
small: EdgeInsets.symmetric(horizontal: 22, vertical: 10),
big: EdgeInsets.symmetric(horizontal: 21, vertical: 8),
return SectionButton(
onPressed: vm.toggleAllowContacts,
icon: Icon(Icons.phone_callback_outlined,
color: theme.getColorFor(ThemeCode.legacyPrimary),
size: 36,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
iconPadding: 8,
body: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: EdgeInsets.only(
bottom: SizeUtils.getByScreen(small: 12, big: 10),
),
child: Text(
context.translate(I18n.whitelistDescription),
style: TextStyle(
fontSize: SizeUtils.getByScreen(small: 14, big: 15),
color:
theme.getColorFor(ThemeCode.textPrimary).withAlpha(178),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(context.translate(I18n.allowContacts),
style: TextStyle(
fontWeight: FontWeight.w500,
fontSize: 14,
color: theme.getColorFor(ThemeCode.textPrimary)
)
),
),
),
...List.generate(contacts.length, (index) {
final contact = contacts[index];
return ContactListContactCard(
contact: contact,
onDelete: () =>
_confirmDelete(context, ref, index, contact.name),
theme: theme,
);
}),
SizedBox(height: SizeUtils.getByScreen(small: 12, big: 10)),
Text(
context.translate(
I18n.allowedNumbersCount,
args: {'count': contacts.length.toString()},
),
style: TextStyle(
fontSize: SizeUtils.getByScreen(small: 13, big: 14),
color: primaryColor,
fontWeight: FontWeight.w500,
),
Text(context.translate(I18n.allowContactsMessage),
style: TextStyle(
fontWeight: FontWeight.w500,
fontSize: 12,
color: theme.getColorFor(ThemeCode.textTertiary)
)
),
],
),
Switch(
value: allowContacts,
onChanged: (_) {
vm.toggleAllowContacts();
},
)
],
),
),
)
);
}
}
void _confirmDelete(
BuildContext context,
WidgetRef ref,
int index,
String name,
) {
class _BlockedCallsSection extends ConsumerWidget {
const _BlockedCallsSection();
@override
Widget build(BuildContext context, WidgetRef ref) {
final theme = ref.read(themePortProvider);
final primaryColor = theme.getColorFor(ThemeCode.legacyPrimary);
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text(context.translate(I18n.removeAllowedNumber)),
content: Text(
context.translate(
I18n.removeAllowedNumberConfirm,
args: {'name': name},
return SectionButton(
onPressed: (){
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => BlockedCallsScreen(),
),
),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: Text(
context.translate(I18n.cancel),
style: TextStyle(color: primaryColor),
),
);
},
icon: Icon(Icons.phone_callback_outlined,
color: theme.getColorFor(ThemeCode.legacyPrimary),
size: 36,
),
iconPadding: 8,
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(context.translate(I18n.allowContacts),
style: TextStyle(
fontWeight: FontWeight.w500,
fontSize: 14,
color: theme.getColorFor(ThemeCode.textPrimary)
)
),
TextButton(
onPressed: () {
ref
.read(blockPhoneViewModelProvider.notifier)
.removeContact(index);
Navigator.pop(context);
},
child: Text(
context.translate(I18n.delete),
style: TextStyle(color: Colors.red),
),
Text(context.translate(I18n.allowContactsMessage),
style: TextStyle(
fontWeight: FontWeight.w500,
fontSize: 12,
color: theme.getColorFor(ThemeCode.textTertiary)
)
),
],
),
);
}
}
}

View File

@@ -0,0 +1,182 @@
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:settings/src/features/block_phone/presentation/state/block_phone_view_model.dart';
import 'package:sf_localizations/sf_localizations.dart';
import 'package:utils/utils.dart';
import '../../../core/presentation/widgets/contact_list_contact_card.dart';
class BlockedCallsScreen extends ConsumerWidget {
const BlockedCallsScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final theme = ref.read(themePortProvider);
final state = ref.watch(blockPhoneViewModelProvider);
final vm = ref.read(blockPhoneViewModelProvider.notifier);
return LegacyPageLayout(
theme: theme,
title: context.translate(I18n.blockedCallsList),
body: state.isLoading
? const Center(child: CircularProgressIndicator())
: state.blockedCalls.isEmpty
? _EmptyState(primaryColor: theme.getColorFor(ThemeCode.legacyPrimary))
: const _ContactList(),
);
}
}
class _EmptyState extends StatelessWidget {
final Color primaryColor;
const _EmptyState({required this.primaryColor});
@override
Widget build(BuildContext context) {
return Center(
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: SizeUtils.getByScreen(small: 32, big: 30),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
Icons.phone_locked_outlined,
color: primaryColor,
size: SizeUtils.getByScreen(small: 120, big: 140),
),
SizedBox(height: SizeUtils.getByScreen(small: 20, big: 24)),
Text(
context.translate(I18n.noBlockedNumbers),
style: TextStyle(
fontSize: SizeUtils.getByScreen(small: 16, big: 17),
fontWeight: FontWeight.w500,
color: Colors.grey,
),
),
SizedBox(height: SizeUtils.getByScreen(small: 8, big: 10)),
Text(
context.translate(I18n.noBlockedNumbersDescription),
textAlign: TextAlign.center,
style: TextStyle(
fontSize: SizeUtils.getByScreen(small: 14, big: 15),
color: Colors.grey,
),
),
],
),
),
);
}
}
class _ContactList extends ConsumerWidget {
const _ContactList();
@override
Widget build(BuildContext context, WidgetRef ref) {
final theme = ref.watch(themePortProvider);
final contacts = ref.watch(
blockPhoneViewModelProvider.select((s) => s.contacts),
);
final primaryColor = theme.getColorFor(ThemeCode.legacyPrimary);
return SingleChildScrollView(
child: Padding(
padding: SizeUtils.getByScreen(
small: EdgeInsets.symmetric(horizontal: 22, vertical: 10),
big: EdgeInsets.symmetric(horizontal: 21, vertical: 8),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.only(
bottom: SizeUtils.getByScreen(small: 12, big: 10),
),
child: Text(
context.translate(I18n.whitelistDescription),
style: TextStyle(
fontSize: SizeUtils.getByScreen(small: 14, big: 15),
color:
theme.getColorFor(ThemeCode.textPrimary).withAlpha(178),
),
),
),
...List.generate(contacts.length, (index) {
final contact = contacts[index];
return ContactListContactCard(
contact: contact,
onDelete: () =>
_confirmDelete(context, ref, index, contact.name),
theme: theme,
);
}),
SizedBox(height: SizeUtils.getByScreen(small: 12, big: 10)),
Text(
context.translate(
I18n.allowedNumbersCount,
args: {'count': contacts.length.toString()},
),
style: TextStyle(
fontSize: SizeUtils.getByScreen(small: 13, big: 14),
color: primaryColor,
fontWeight: FontWeight.w500,
),
),
],
),
),
);
}
void _confirmDelete(
BuildContext context,
WidgetRef ref,
int index,
String name,
) {
final theme = ref.read(themePortProvider);
final primaryColor = theme.getColorFor(ThemeCode.legacyPrimary);
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text(context.translate(I18n.removeAllowedNumber)),
content: Text(
context.translate(
I18n.removeAllowedNumberConfirm,
args: {'name': name},
),
),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: Text(
context.translate(I18n.cancel),
style: TextStyle(color: primaryColor),
),
),
TextButton(
onPressed: () {
ref
.read(blockPhoneViewModelProvider.notifier)
.removeContact(index);
Navigator.pop(context);
},
child: Text(
context.translate(I18n.delete),
style: TextStyle(color: Colors.red),
),
),
],
),
);
}
}

View File

@@ -26,8 +26,9 @@ class BlockPhoneViewModel extends Notifier<BlockPhoneViewState> {
final device = ref.read(selectedDeviceProvider);
if (device == null) return;
final contacts = await _repository.getWhitelist(deviceId: device.id);
state = state.copyWith(contacts: contacts, isLoading: false);
// final contacts = await _contactsRepository
final whitelist = await _repository.getWhitelist(deviceId: device.id);
state = state.copyWith(whitelist: whitelist, isLoading: false);
} catch (e) {
state = state.copyWith(
isLoading: false,
@@ -43,7 +44,7 @@ class BlockPhoneViewModel extends Notifier<BlockPhoneViewState> {
final device = ref.read(selectedDeviceProvider);
if (device == null) return;
final updatedContacts = [...state.contacts, contact];
final updatedContacts = [...state.whitelist, contact];
await _repository.upsertWhitelist(
userId: device.userId ?? '',
@@ -52,7 +53,7 @@ class BlockPhoneViewModel extends Notifier<BlockPhoneViewState> {
);
state = state.copyWith(
contacts: updatedContacts,
whitelist: updatedContacts,
isSaving: false,
successMessage: I18n.numberAdded,
);
@@ -71,7 +72,7 @@ class BlockPhoneViewModel extends Notifier<BlockPhoneViewState> {
final device = ref.read(selectedDeviceProvider);
if (device == null) return;
final updatedContacts = [...state.contacts]..removeAt(index);
final updatedContacts = [...state.whitelist]..removeAt(index);
await _repository.upsertWhitelist(
userId: device.userId ?? '',
@@ -80,7 +81,7 @@ class BlockPhoneViewModel extends Notifier<BlockPhoneViewState> {
);
state = state.copyWith(
contacts: updatedContacts,
whitelist: updatedContacts,
isSaving: false,
successMessage: I18n.numberRemoved,
);
@@ -92,6 +93,33 @@ class BlockPhoneViewModel extends Notifier<BlockPhoneViewState> {
}
}
Future<void> toggleAllowContacts() async {
final device = ref.read(selectedDeviceProvider);
if (device == null) return;
try {
state = state.copyWith(
isSaving: true,
);
await _repository.upsertWhitelist(
userId: device.userId ?? '',
deviceId: device.id,
contacts: state.whitelist,
);
state = state.copyWith(
isSaving: false,
allowContacts: !state.allowContacts
);
} catch(e) {
state = state.copyWith(
isSaving: false,
errorMessage: e.toString(),
);
}
}
void clearSuccess() {
state = state.copyWith(successMessage: '');
}

View File

@@ -1,4 +1,5 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:legacy_shared/legacy_shared.dart';
import 'package:settings/src/core/domain/entities/contact_list_contact_entity.dart';
part 'block_phone_view_state.freezed.dart';
@@ -7,8 +8,12 @@ part 'block_phone_view_state.freezed.dart';
abstract class BlockPhoneViewState with _$BlockPhoneViewState {
const factory BlockPhoneViewState({
@Default([]) List<ContactListContactEntity> contacts,
@Default([]) List<ContactListContactEntity> whitelist,
@Default([]) List<CallHistoryEntity> blockedCalls,
@Default(10) int maxLimit,
@Default(true) bool isLoading,
@Default(false) bool isSaving,
@Default(false) bool allowContacts,
@Default('') String successMessage,
@Default('') String errorMessage,
}) = _BlockPhoneViewState;

View File

@@ -14,7 +14,7 @@ T _$identity<T>(T value) => value;
/// @nodoc
mixin _$BlockPhoneViewState {
List<ContactListContactEntity> get contacts; bool get isLoading; bool get isSaving; String get successMessage; String get errorMessage;
List<ContactListContactEntity> get contacts; List<ContactListContactEntity> get whitelist; List<CallHistoryEntity> get blockedCalls; int get maxLimit; bool get isLoading; bool get isSaving; bool get allowContacts; String get successMessage; String get errorMessage;
/// Create a copy of BlockPhoneViewState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -25,16 +25,16 @@ $BlockPhoneViewStateCopyWith<BlockPhoneViewState> get copyWith => _$BlockPhoneVi
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is BlockPhoneViewState&&const DeepCollectionEquality().equals(other.contacts, contacts)&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.isSaving, isSaving) || other.isSaving == isSaving)&&(identical(other.successMessage, successMessage) || other.successMessage == successMessage)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage));
return identical(this, other) || (other.runtimeType == runtimeType&&other is BlockPhoneViewState&&const DeepCollectionEquality().equals(other.contacts, contacts)&&const DeepCollectionEquality().equals(other.whitelist, whitelist)&&const DeepCollectionEquality().equals(other.blockedCalls, blockedCalls)&&(identical(other.maxLimit, maxLimit) || other.maxLimit == maxLimit)&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.isSaving, isSaving) || other.isSaving == isSaving)&&(identical(other.allowContacts, allowContacts) || other.allowContacts == allowContacts)&&(identical(other.successMessage, successMessage) || other.successMessage == successMessage)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage));
}
@override
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(contacts),isLoading,isSaving,successMessage,errorMessage);
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(contacts),const DeepCollectionEquality().hash(whitelist),const DeepCollectionEquality().hash(blockedCalls),maxLimit,isLoading,isSaving,allowContacts,successMessage,errorMessage);
@override
String toString() {
return 'BlockPhoneViewState(contacts: $contacts, isLoading: $isLoading, isSaving: $isSaving, successMessage: $successMessage, errorMessage: $errorMessage)';
return 'BlockPhoneViewState(contacts: $contacts, whitelist: $whitelist, blockedCalls: $blockedCalls, maxLimit: $maxLimit, isLoading: $isLoading, isSaving: $isSaving, allowContacts: $allowContacts, successMessage: $successMessage, errorMessage: $errorMessage)';
}
@@ -45,7 +45,7 @@ abstract mixin class $BlockPhoneViewStateCopyWith<$Res> {
factory $BlockPhoneViewStateCopyWith(BlockPhoneViewState value, $Res Function(BlockPhoneViewState) _then) = _$BlockPhoneViewStateCopyWithImpl;
@useResult
$Res call({
List<ContactListContactEntity> contacts, bool isLoading, bool isSaving, String successMessage, String errorMessage
List<ContactListContactEntity> contacts, List<ContactListContactEntity> whitelist, List<CallHistoryEntity> blockedCalls, int maxLimit, bool isLoading, bool isSaving, bool allowContacts, String successMessage, String errorMessage
});
@@ -62,11 +62,15 @@ class _$BlockPhoneViewStateCopyWithImpl<$Res>
/// Create a copy of BlockPhoneViewState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? contacts = null,Object? isLoading = null,Object? isSaving = null,Object? successMessage = null,Object? errorMessage = null,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? contacts = null,Object? whitelist = null,Object? blockedCalls = null,Object? maxLimit = null,Object? isLoading = null,Object? isSaving = null,Object? allowContacts = null,Object? successMessage = null,Object? errorMessage = null,}) {
return _then(_self.copyWith(
contacts: null == contacts ? _self.contacts : contacts // ignore: cast_nullable_to_non_nullable
as List<ContactListContactEntity>,isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable
as List<ContactListContactEntity>,whitelist: null == whitelist ? _self.whitelist : whitelist // ignore: cast_nullable_to_non_nullable
as List<ContactListContactEntity>,blockedCalls: null == blockedCalls ? _self.blockedCalls : blockedCalls // ignore: cast_nullable_to_non_nullable
as List<CallHistoryEntity>,maxLimit: null == maxLimit ? _self.maxLimit : maxLimit // ignore: cast_nullable_to_non_nullable
as int,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,allowContacts: null == allowContacts ? _self.allowContacts : allowContacts // ignore: cast_nullable_to_non_nullable
as bool,successMessage: null == successMessage ? _self.successMessage : successMessage // ignore: cast_nullable_to_non_nullable
as String,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
as String,
@@ -154,10 +158,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( List<ContactListContactEntity> contacts, bool isLoading, bool isSaving, String successMessage, String errorMessage)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( List<ContactListContactEntity> contacts, List<ContactListContactEntity> whitelist, List<CallHistoryEntity> blockedCalls, int maxLimit, bool isLoading, bool isSaving, bool allowContacts, String successMessage, String errorMessage)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _BlockPhoneViewState() when $default != null:
return $default(_that.contacts,_that.isLoading,_that.isSaving,_that.successMessage,_that.errorMessage);case _:
return $default(_that.contacts,_that.whitelist,_that.blockedCalls,_that.maxLimit,_that.isLoading,_that.isSaving,_that.allowContacts,_that.successMessage,_that.errorMessage);case _:
return orElse();
}
@@ -175,10 +179,10 @@ return $default(_that.contacts,_that.isLoading,_that.isSaving,_that.successMessa
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( List<ContactListContactEntity> contacts, bool isLoading, bool isSaving, String successMessage, String errorMessage) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( List<ContactListContactEntity> contacts, List<ContactListContactEntity> whitelist, List<CallHistoryEntity> blockedCalls, int maxLimit, bool isLoading, bool isSaving, bool allowContacts, String successMessage, String errorMessage) $default,) {final _that = this;
switch (_that) {
case _BlockPhoneViewState():
return $default(_that.contacts,_that.isLoading,_that.isSaving,_that.successMessage,_that.errorMessage);case _:
return $default(_that.contacts,_that.whitelist,_that.blockedCalls,_that.maxLimit,_that.isLoading,_that.isSaving,_that.allowContacts,_that.successMessage,_that.errorMessage);case _:
throw StateError('Unexpected subclass');
}
@@ -195,10 +199,10 @@ return $default(_that.contacts,_that.isLoading,_that.isSaving,_that.successMessa
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( List<ContactListContactEntity> contacts, bool isLoading, bool isSaving, String successMessage, String errorMessage)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( List<ContactListContactEntity> contacts, List<ContactListContactEntity> whitelist, List<CallHistoryEntity> blockedCalls, int maxLimit, bool isLoading, bool isSaving, bool allowContacts, String successMessage, String errorMessage)? $default,) {final _that = this;
switch (_that) {
case _BlockPhoneViewState() when $default != null:
return $default(_that.contacts,_that.isLoading,_that.isSaving,_that.successMessage,_that.errorMessage);case _:
return $default(_that.contacts,_that.whitelist,_that.blockedCalls,_that.maxLimit,_that.isLoading,_that.isSaving,_that.allowContacts,_that.successMessage,_that.errorMessage);case _:
return null;
}
@@ -210,7 +214,7 @@ return $default(_that.contacts,_that.isLoading,_that.isSaving,_that.successMessa
class _BlockPhoneViewState implements BlockPhoneViewState {
const _BlockPhoneViewState({final List<ContactListContactEntity> contacts = const [], this.isLoading = true, this.isSaving = false, this.successMessage = '', this.errorMessage = ''}): _contacts = contacts;
const _BlockPhoneViewState({final List<ContactListContactEntity> contacts = const [], final List<ContactListContactEntity> whitelist = const [], final List<CallHistoryEntity> blockedCalls = const [], this.maxLimit = 10, this.isLoading = true, this.isSaving = false, this.allowContacts = false, this.successMessage = '', this.errorMessage = ''}): _contacts = contacts,_whitelist = whitelist,_blockedCalls = blockedCalls;
final List<ContactListContactEntity> _contacts;
@@ -220,8 +224,24 @@ class _BlockPhoneViewState implements BlockPhoneViewState {
return EqualUnmodifiableListView(_contacts);
}
final List<ContactListContactEntity> _whitelist;
@override@JsonKey() List<ContactListContactEntity> get whitelist {
if (_whitelist is EqualUnmodifiableListView) return _whitelist;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_whitelist);
}
final List<CallHistoryEntity> _blockedCalls;
@override@JsonKey() List<CallHistoryEntity> get blockedCalls {
if (_blockedCalls is EqualUnmodifiableListView) return _blockedCalls;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_blockedCalls);
}
@override@JsonKey() final int maxLimit;
@override@JsonKey() final bool isLoading;
@override@JsonKey() final bool isSaving;
@override@JsonKey() final bool allowContacts;
@override@JsonKey() final String successMessage;
@override@JsonKey() final String errorMessage;
@@ -235,16 +255,16 @@ _$BlockPhoneViewStateCopyWith<_BlockPhoneViewState> get copyWith => __$BlockPhon
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _BlockPhoneViewState&&const DeepCollectionEquality().equals(other._contacts, _contacts)&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.isSaving, isSaving) || other.isSaving == isSaving)&&(identical(other.successMessage, successMessage) || other.successMessage == successMessage)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage));
return identical(this, other) || (other.runtimeType == runtimeType&&other is _BlockPhoneViewState&&const DeepCollectionEquality().equals(other._contacts, _contacts)&&const DeepCollectionEquality().equals(other._whitelist, _whitelist)&&const DeepCollectionEquality().equals(other._blockedCalls, _blockedCalls)&&(identical(other.maxLimit, maxLimit) || other.maxLimit == maxLimit)&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.isSaving, isSaving) || other.isSaving == isSaving)&&(identical(other.allowContacts, allowContacts) || other.allowContacts == allowContacts)&&(identical(other.successMessage, successMessage) || other.successMessage == successMessage)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage));
}
@override
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_contacts),isLoading,isSaving,successMessage,errorMessage);
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_contacts),const DeepCollectionEquality().hash(_whitelist),const DeepCollectionEquality().hash(_blockedCalls),maxLimit,isLoading,isSaving,allowContacts,successMessage,errorMessage);
@override
String toString() {
return 'BlockPhoneViewState(contacts: $contacts, isLoading: $isLoading, isSaving: $isSaving, successMessage: $successMessage, errorMessage: $errorMessage)';
return 'BlockPhoneViewState(contacts: $contacts, whitelist: $whitelist, blockedCalls: $blockedCalls, maxLimit: $maxLimit, isLoading: $isLoading, isSaving: $isSaving, allowContacts: $allowContacts, successMessage: $successMessage, errorMessage: $errorMessage)';
}
@@ -255,7 +275,7 @@ abstract mixin class _$BlockPhoneViewStateCopyWith<$Res> implements $BlockPhoneV
factory _$BlockPhoneViewStateCopyWith(_BlockPhoneViewState value, $Res Function(_BlockPhoneViewState) _then) = __$BlockPhoneViewStateCopyWithImpl;
@override @useResult
$Res call({
List<ContactListContactEntity> contacts, bool isLoading, bool isSaving, String successMessage, String errorMessage
List<ContactListContactEntity> contacts, List<ContactListContactEntity> whitelist, List<CallHistoryEntity> blockedCalls, int maxLimit, bool isLoading, bool isSaving, bool allowContacts, String successMessage, String errorMessage
});
@@ -272,11 +292,15 @@ class __$BlockPhoneViewStateCopyWithImpl<$Res>
/// Create a copy of BlockPhoneViewState
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? contacts = null,Object? isLoading = null,Object? isSaving = null,Object? successMessage = null,Object? errorMessage = null,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? contacts = null,Object? whitelist = null,Object? blockedCalls = null,Object? maxLimit = null,Object? isLoading = null,Object? isSaving = null,Object? allowContacts = null,Object? successMessage = null,Object? errorMessage = null,}) {
return _then(_BlockPhoneViewState(
contacts: null == contacts ? _self._contacts : contacts // ignore: cast_nullable_to_non_nullable
as List<ContactListContactEntity>,isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable
as List<ContactListContactEntity>,whitelist: null == whitelist ? _self._whitelist : whitelist // ignore: cast_nullable_to_non_nullable
as List<ContactListContactEntity>,blockedCalls: null == blockedCalls ? _self._blockedCalls : blockedCalls // ignore: cast_nullable_to_non_nullable
as List<CallHistoryEntity>,maxLimit: null == maxLimit ? _self.maxLimit : maxLimit // ignore: cast_nullable_to_non_nullable
as int,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,allowContacts: null == allowContacts ? _self.allowContacts : allowContacts // ignore: cast_nullable_to_non_nullable
as bool,successMessage: null == successMessage ? _self.successMessage : successMessage // ignore: cast_nullable_to_non_nullable
as String,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
as String,

View File

@@ -14,8 +14,10 @@ class RemoteOnOffScreen extends ConsumerWidget {
return LegacyPageLayout(
theme: theme,
title: context.translate(I18n.remoteOnOff),
body: const Center(
child: Text('Coming soon'),
body: Column(
children: [
],
),
);
}

View File

@@ -17,4 +17,5 @@ export 'src/providers/commands_repository_provider.dart';
export 'src/domain/repositories/devices_repository.dart';
export 'src/providers/devices_repository_provider.dart';
export 'src/data/datasources/device_settings_update_datasource.dart';
export 'src/providers/device_settings_update_provider.dart';
export 'src/providers/device_settings_update_provider.dart';
export 'src/data/models/entities/call_history_entity.dart';

View File

@@ -837,5 +837,6 @@
"takingPhoto": "Taking photo...",
"errorTakePicture": "Error taking photo",
"errorFetchPhotos": "Error fetching photos",
"errorCall": "Error making call"
"errorCall": "Error making call",
"blockedCallsList": "Blocked calls list"
}

View File

@@ -835,5 +835,6 @@
"takingPhoto": "Tomando foto...",
"errorTakePicture": "Error al tomar la foto",
"errorFetchPhotos": "Error al obtener las fotos",
"errorCall": "Error al realizar la llamada"
"errorCall": "Error al realizar la llamada",
"blockedCallsList": "Lista de llamadas bloqueados"
}

View File

@@ -840,4 +840,7 @@ class I18n {
static const String errorTakePicture = 'errorTakePicture';
static const String errorFetchPhotos = 'errorFetchPhotos';
static const String errorCall = 'errorCall';
static const String blockedCallsList = 'blockedCallsList';
static const String allowContacts = 'allowContacts';
static const String allowContactsMessage = 'allowContactsMessage';
}