feat(wifi-settings): redesign with device commands, WebSocket scan, and connect flow
This commit is contained in:
@@ -1,13 +1,16 @@
|
||||
import 'package:settings/src/core/data/models/create_wifi_network_request_model.dart';
|
||||
import 'package:settings/src/core/data/models/get_wifi_networks_response_model.dart';
|
||||
import 'package:settings/src/features/wifi_settings/domain/entities/wifi_network_entity.dart';
|
||||
|
||||
abstract class WifiRemoteDatasource {
|
||||
Future<GetWifiNetworksResponseModel> getWifiNetworks({
|
||||
required String deviceId,
|
||||
Future<List<WifiNetworkEntity>> getWifiNetworks({
|
||||
required String deviceIdentificator,
|
||||
});
|
||||
|
||||
Future<void> createWifiNetwork({
|
||||
required CreateWifiNetworkRequestModel request,
|
||||
required String id,
|
||||
required String deviceIdentificator,
|
||||
required String ssid,
|
||||
required String bssid,
|
||||
required String password,
|
||||
});
|
||||
|
||||
Future<void> deleteWifiNetwork({required String networkId});
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'package:dio/dio.dart';
|
||||
import 'package:legacy_shared/legacy_shared.dart';
|
||||
import 'package:sf_infrastructure/sf_infrastructure.dart';
|
||||
|
||||
import '../../../features/wifi_settings/domain/entities/wifi_network_entity.dart';
|
||||
import '../models/create_wifi_network_request_model.dart';
|
||||
import '../models/get_wifi_networks_response_model.dart';
|
||||
import 'wifi_remote_datasource.dart';
|
||||
@@ -12,29 +13,39 @@ class WifiRemoteDatasourceImpl implements WifiRemoteDatasource {
|
||||
final SaveFamilyRepository _repository;
|
||||
|
||||
@override
|
||||
Future<GetWifiNetworksResponseModel> getWifiNetworks({
|
||||
required String deviceId,
|
||||
Future<List<WifiNetworkEntity>> getWifiNetworks({
|
||||
required String deviceIdentificator,
|
||||
}) async {
|
||||
try {
|
||||
final response = await _repository.get<Map<String, dynamic>>(
|
||||
'/devices/$deviceId/wifi-networks',
|
||||
'/devices/identificator/$deviceIdentificator/wifi-networks',
|
||||
);
|
||||
|
||||
final data = response.data;
|
||||
if (data == null || data.isEmpty) {
|
||||
return const GetWifiNetworksResponseModel(total: 0, items: []);
|
||||
}
|
||||
if (data == null || data.isEmpty) return [];
|
||||
|
||||
return GetWifiNetworksResponseModel.fromJson(data);
|
||||
return GetWifiNetworksResponseModel.fromJson(data).toEntities();
|
||||
} on DioException catch (error) {
|
||||
if (error.response?.statusCode == 404) return [];
|
||||
throw mapDioError(error, defaultMessage: 'Error getting WiFi networks');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> createWifiNetwork({
|
||||
required CreateWifiNetworkRequestModel request,
|
||||
required String id,
|
||||
required String deviceIdentificator,
|
||||
required String ssid,
|
||||
required String bssid,
|
||||
required String password,
|
||||
}) async {
|
||||
final request = CreateWifiNetworkRequestModel(
|
||||
id: id,
|
||||
deviceIdentificator: deviceIdentificator,
|
||||
ssid: ssid,
|
||||
bssid: bssid,
|
||||
password: password,
|
||||
);
|
||||
await safeCall(
|
||||
() => _repository.post<dynamic>('/wifi-networks', body: request.toJson()),
|
||||
'Error creating WiFi network',
|
||||
|
||||
@@ -8,9 +8,10 @@ abstract class CreateWifiNetworkRequestModel
|
||||
with _$CreateWifiNetworkRequestModel {
|
||||
const factory CreateWifiNetworkRequestModel({
|
||||
required String id,
|
||||
required String deviceId,
|
||||
required String deviceIdentificator,
|
||||
required String ssid,
|
||||
required String bssid,
|
||||
required String password,
|
||||
}) = _CreateWifiNetworkRequestModel;
|
||||
|
||||
factory CreateWifiNetworkRequestModel.fromJson(Map<String, dynamic> json) =>
|
||||
|
||||
@@ -15,7 +15,7 @@ T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$CreateWifiNetworkRequestModel {
|
||||
|
||||
String get id; String get deviceId; String get ssid; String get bssid;
|
||||
String get id; String get deviceIdentificator; String get ssid; String get bssid; String get password;
|
||||
/// Create a copy of CreateWifiNetworkRequestModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@@ -28,16 +28,16 @@ $CreateWifiNetworkRequestModelCopyWith<CreateWifiNetworkRequestModel> get copyWi
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is CreateWifiNetworkRequestModel&&(identical(other.id, id) || other.id == id)&&(identical(other.deviceId, deviceId) || other.deviceId == deviceId)&&(identical(other.ssid, ssid) || other.ssid == ssid)&&(identical(other.bssid, bssid) || other.bssid == bssid));
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is CreateWifiNetworkRequestModel&&(identical(other.id, id) || other.id == id)&&(identical(other.deviceIdentificator, deviceIdentificator) || other.deviceIdentificator == deviceIdentificator)&&(identical(other.ssid, ssid) || other.ssid == ssid)&&(identical(other.bssid, bssid) || other.bssid == bssid)&&(identical(other.password, password) || other.password == password));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,id,deviceId,ssid,bssid);
|
||||
int get hashCode => Object.hash(runtimeType,id,deviceIdentificator,ssid,bssid,password);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'CreateWifiNetworkRequestModel(id: $id, deviceId: $deviceId, ssid: $ssid, bssid: $bssid)';
|
||||
return 'CreateWifiNetworkRequestModel(id: $id, deviceIdentificator: $deviceIdentificator, ssid: $ssid, bssid: $bssid, password: $password)';
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ abstract mixin class $CreateWifiNetworkRequestModelCopyWith<$Res> {
|
||||
factory $CreateWifiNetworkRequestModelCopyWith(CreateWifiNetworkRequestModel value, $Res Function(CreateWifiNetworkRequestModel) _then) = _$CreateWifiNetworkRequestModelCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String id, String deviceId, String ssid, String bssid
|
||||
String id, String deviceIdentificator, String ssid, String bssid, String password
|
||||
});
|
||||
|
||||
|
||||
@@ -65,12 +65,13 @@ class _$CreateWifiNetworkRequestModelCopyWithImpl<$Res>
|
||||
|
||||
/// Create a copy of CreateWifiNetworkRequestModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? deviceId = null,Object? ssid = null,Object? bssid = null,}) {
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? deviceIdentificator = null,Object? ssid = null,Object? bssid = null,Object? password = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,deviceId: null == deviceId ? _self.deviceId : deviceId // ignore: cast_nullable_to_non_nullable
|
||||
as String,deviceIdentificator: null == deviceIdentificator ? _self.deviceIdentificator : deviceIdentificator // ignore: cast_nullable_to_non_nullable
|
||||
as String,ssid: null == ssid ? _self.ssid : ssid // ignore: cast_nullable_to_non_nullable
|
||||
as String,bssid: null == bssid ? _self.bssid : bssid // ignore: cast_nullable_to_non_nullable
|
||||
as String,password: null == password ? _self.password : password // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
@@ -156,10 +157,10 @@ return $default(_that);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String deviceId, String ssid, String bssid)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String deviceIdentificator, String ssid, String bssid, String password)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _CreateWifiNetworkRequestModel() when $default != null:
|
||||
return $default(_that.id,_that.deviceId,_that.ssid,_that.bssid);case _:
|
||||
return $default(_that.id,_that.deviceIdentificator,_that.ssid,_that.bssid,_that.password);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
@@ -177,10 +178,10 @@ return $default(_that.id,_that.deviceId,_that.ssid,_that.bssid);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String deviceId, String ssid, String bssid) $default,) {final _that = this;
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String deviceIdentificator, String ssid, String bssid, String password) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _CreateWifiNetworkRequestModel():
|
||||
return $default(_that.id,_that.deviceId,_that.ssid,_that.bssid);case _:
|
||||
return $default(_that.id,_that.deviceIdentificator,_that.ssid,_that.bssid,_that.password);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
@@ -197,10 +198,10 @@ return $default(_that.id,_that.deviceId,_that.ssid,_that.bssid);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String deviceId, String ssid, String bssid)? $default,) {final _that = this;
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String deviceIdentificator, String ssid, String bssid, String password)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _CreateWifiNetworkRequestModel() when $default != null:
|
||||
return $default(_that.id,_that.deviceId,_that.ssid,_that.bssid);case _:
|
||||
return $default(_that.id,_that.deviceIdentificator,_that.ssid,_that.bssid,_that.password);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
@@ -212,13 +213,14 @@ return $default(_that.id,_that.deviceId,_that.ssid,_that.bssid);case _:
|
||||
@JsonSerializable()
|
||||
|
||||
class _CreateWifiNetworkRequestModel implements CreateWifiNetworkRequestModel {
|
||||
const _CreateWifiNetworkRequestModel({required this.id, required this.deviceId, required this.ssid, required this.bssid});
|
||||
const _CreateWifiNetworkRequestModel({required this.id, required this.deviceIdentificator, required this.ssid, required this.bssid, required this.password});
|
||||
factory _CreateWifiNetworkRequestModel.fromJson(Map<String, dynamic> json) => _$CreateWifiNetworkRequestModelFromJson(json);
|
||||
|
||||
@override final String id;
|
||||
@override final String deviceId;
|
||||
@override final String deviceIdentificator;
|
||||
@override final String ssid;
|
||||
@override final String bssid;
|
||||
@override final String password;
|
||||
|
||||
/// Create a copy of CreateWifiNetworkRequestModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@@ -233,16 +235,16 @@ Map<String, dynamic> toJson() {
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _CreateWifiNetworkRequestModel&&(identical(other.id, id) || other.id == id)&&(identical(other.deviceId, deviceId) || other.deviceId == deviceId)&&(identical(other.ssid, ssid) || other.ssid == ssid)&&(identical(other.bssid, bssid) || other.bssid == bssid));
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _CreateWifiNetworkRequestModel&&(identical(other.id, id) || other.id == id)&&(identical(other.deviceIdentificator, deviceIdentificator) || other.deviceIdentificator == deviceIdentificator)&&(identical(other.ssid, ssid) || other.ssid == ssid)&&(identical(other.bssid, bssid) || other.bssid == bssid)&&(identical(other.password, password) || other.password == password));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,id,deviceId,ssid,bssid);
|
||||
int get hashCode => Object.hash(runtimeType,id,deviceIdentificator,ssid,bssid,password);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'CreateWifiNetworkRequestModel(id: $id, deviceId: $deviceId, ssid: $ssid, bssid: $bssid)';
|
||||
return 'CreateWifiNetworkRequestModel(id: $id, deviceIdentificator: $deviceIdentificator, ssid: $ssid, bssid: $bssid, password: $password)';
|
||||
}
|
||||
|
||||
|
||||
@@ -253,7 +255,7 @@ abstract mixin class _$CreateWifiNetworkRequestModelCopyWith<$Res> implements $C
|
||||
factory _$CreateWifiNetworkRequestModelCopyWith(_CreateWifiNetworkRequestModel value, $Res Function(_CreateWifiNetworkRequestModel) _then) = __$CreateWifiNetworkRequestModelCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String id, String deviceId, String ssid, String bssid
|
||||
String id, String deviceIdentificator, String ssid, String bssid, String password
|
||||
});
|
||||
|
||||
|
||||
@@ -270,12 +272,13 @@ class __$CreateWifiNetworkRequestModelCopyWithImpl<$Res>
|
||||
|
||||
/// Create a copy of CreateWifiNetworkRequestModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? deviceId = null,Object? ssid = null,Object? bssid = null,}) {
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? deviceIdentificator = null,Object? ssid = null,Object? bssid = null,Object? password = null,}) {
|
||||
return _then(_CreateWifiNetworkRequestModel(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,deviceId: null == deviceId ? _self.deviceId : deviceId // ignore: cast_nullable_to_non_nullable
|
||||
as String,deviceIdentificator: null == deviceIdentificator ? _self.deviceIdentificator : deviceIdentificator // ignore: cast_nullable_to_non_nullable
|
||||
as String,ssid: null == ssid ? _self.ssid : ssid // ignore: cast_nullable_to_non_nullable
|
||||
as String,bssid: null == bssid ? _self.bssid : bssid // ignore: cast_nullable_to_non_nullable
|
||||
as String,password: null == password ? _self.password : password // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
@@ -10,16 +10,18 @@ _CreateWifiNetworkRequestModel _$CreateWifiNetworkRequestModelFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _CreateWifiNetworkRequestModel(
|
||||
id: json['id'] as String,
|
||||
deviceId: json['deviceId'] as String,
|
||||
deviceIdentificator: json['deviceIdentificator'] as String,
|
||||
ssid: json['ssid'] as String,
|
||||
bssid: json['bssid'] as String,
|
||||
password: json['password'] as String,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$CreateWifiNetworkRequestModelToJson(
|
||||
_CreateWifiNetworkRequestModel instance,
|
||||
) => <String, dynamic>{
|
||||
'id': instance.id,
|
||||
'deviceId': instance.deviceId,
|
||||
'deviceIdentificator': instance.deviceIdentificator,
|
||||
'ssid': instance.ssid,
|
||||
'bssid': instance.bssid,
|
||||
'password': instance.password,
|
||||
};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:settings/src/features/wifi_settings/domain/entities/wifi_network_entity.dart';
|
||||
|
||||
part 'get_wifi_networks_response_model.freezed.dart';
|
||||
part 'get_wifi_networks_response_model.g.dart';
|
||||
@@ -7,8 +8,8 @@ part 'get_wifi_networks_response_model.g.dart';
|
||||
abstract class GetWifiNetworksResponseModel
|
||||
with _$GetWifiNetworksResponseModel {
|
||||
const factory GetWifiNetworksResponseModel({
|
||||
required int total,
|
||||
required List<WifiNetworkItemResponseModel> items,
|
||||
@Default(0) int total,
|
||||
@Default([]) List<WifiNetworkItemResponseModel> items,
|
||||
}) = _GetWifiNetworksResponseModel;
|
||||
|
||||
factory GetWifiNetworksResponseModel.fromJson(Map<String, dynamic> json) =>
|
||||
@@ -20,13 +21,31 @@ abstract class WifiNetworkItemResponseModel
|
||||
with _$WifiNetworkItemResponseModel {
|
||||
const factory WifiNetworkItemResponseModel({
|
||||
required String id,
|
||||
required String deviceId,
|
||||
@Default('') String deviceIdentificator,
|
||||
required String ssid,
|
||||
required String bssid,
|
||||
required int createdAt,
|
||||
String? password,
|
||||
int? createdAt,
|
||||
int? updatedAt,
|
||||
}) = _WifiNetworkItemResponseModel;
|
||||
|
||||
factory WifiNetworkItemResponseModel.fromJson(Map<String, dynamic> json) =>
|
||||
_$WifiNetworkItemResponseModelFromJson(json);
|
||||
}
|
||||
|
||||
extension WifiNetworkResponseMapper on GetWifiNetworksResponseModel {
|
||||
List<WifiNetworkEntity> toEntities() {
|
||||
return items
|
||||
.map(
|
||||
(item) => WifiNetworkEntity(
|
||||
id: item.id,
|
||||
ssid: item.ssid,
|
||||
bssid: item.bssid,
|
||||
password: item.password,
|
||||
deviceIdentificator: item.deviceIdentificator,
|
||||
createdAt: item.createdAt,
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,12 +210,12 @@ return $default(_that.total,_that.items);case _:
|
||||
@JsonSerializable()
|
||||
|
||||
class _GetWifiNetworksResponseModel implements GetWifiNetworksResponseModel {
|
||||
const _GetWifiNetworksResponseModel({required this.total, required final List<WifiNetworkItemResponseModel> items}): _items = items;
|
||||
const _GetWifiNetworksResponseModel({this.total = 0, final List<WifiNetworkItemResponseModel> items = const []}): _items = items;
|
||||
factory _GetWifiNetworksResponseModel.fromJson(Map<String, dynamic> json) => _$GetWifiNetworksResponseModelFromJson(json);
|
||||
|
||||
@override final int total;
|
||||
@override@JsonKey() final int total;
|
||||
final List<WifiNetworkItemResponseModel> _items;
|
||||
@override List<WifiNetworkItemResponseModel> get items {
|
||||
@override@JsonKey() List<WifiNetworkItemResponseModel> get items {
|
||||
if (_items is EqualUnmodifiableListView) return _items;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_items);
|
||||
@@ -287,7 +287,7 @@ as List<WifiNetworkItemResponseModel>,
|
||||
/// @nodoc
|
||||
mixin _$WifiNetworkItemResponseModel {
|
||||
|
||||
String get id; String get deviceId; String get ssid; String get bssid; int get createdAt; int? get updatedAt;
|
||||
String get id; String get deviceIdentificator; String get ssid; String get bssid; String? get password; int? get createdAt; int? get updatedAt;
|
||||
/// Create a copy of WifiNetworkItemResponseModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@@ -300,16 +300,16 @@ $WifiNetworkItemResponseModelCopyWith<WifiNetworkItemResponseModel> get copyWith
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is WifiNetworkItemResponseModel&&(identical(other.id, id) || other.id == id)&&(identical(other.deviceId, deviceId) || other.deviceId == deviceId)&&(identical(other.ssid, ssid) || other.ssid == ssid)&&(identical(other.bssid, bssid) || other.bssid == bssid)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt));
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is WifiNetworkItemResponseModel&&(identical(other.id, id) || other.id == id)&&(identical(other.deviceIdentificator, deviceIdentificator) || other.deviceIdentificator == deviceIdentificator)&&(identical(other.ssid, ssid) || other.ssid == ssid)&&(identical(other.bssid, bssid) || other.bssid == bssid)&&(identical(other.password, password) || other.password == password)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,id,deviceId,ssid,bssid,createdAt,updatedAt);
|
||||
int get hashCode => Object.hash(runtimeType,id,deviceIdentificator,ssid,bssid,password,createdAt,updatedAt);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'WifiNetworkItemResponseModel(id: $id, deviceId: $deviceId, ssid: $ssid, bssid: $bssid, createdAt: $createdAt, updatedAt: $updatedAt)';
|
||||
return 'WifiNetworkItemResponseModel(id: $id, deviceIdentificator: $deviceIdentificator, ssid: $ssid, bssid: $bssid, password: $password, createdAt: $createdAt, updatedAt: $updatedAt)';
|
||||
}
|
||||
|
||||
|
||||
@@ -320,7 +320,7 @@ abstract mixin class $WifiNetworkItemResponseModelCopyWith<$Res> {
|
||||
factory $WifiNetworkItemResponseModelCopyWith(WifiNetworkItemResponseModel value, $Res Function(WifiNetworkItemResponseModel) _then) = _$WifiNetworkItemResponseModelCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String id, String deviceId, String ssid, String bssid, int createdAt, int? updatedAt
|
||||
String id, String deviceIdentificator, String ssid, String bssid, String? password, int? createdAt, int? updatedAt
|
||||
});
|
||||
|
||||
|
||||
@@ -337,14 +337,15 @@ class _$WifiNetworkItemResponseModelCopyWithImpl<$Res>
|
||||
|
||||
/// Create a copy of WifiNetworkItemResponseModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? deviceId = null,Object? ssid = null,Object? bssid = null,Object? createdAt = null,Object? updatedAt = freezed,}) {
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? deviceIdentificator = null,Object? ssid = null,Object? bssid = null,Object? password = freezed,Object? createdAt = freezed,Object? updatedAt = freezed,}) {
|
||||
return _then(_self.copyWith(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,deviceId: null == deviceId ? _self.deviceId : deviceId // ignore: cast_nullable_to_non_nullable
|
||||
as String,deviceIdentificator: null == deviceIdentificator ? _self.deviceIdentificator : deviceIdentificator // ignore: cast_nullable_to_non_nullable
|
||||
as String,ssid: null == ssid ? _self.ssid : ssid // ignore: cast_nullable_to_non_nullable
|
||||
as String,bssid: null == bssid ? _self.bssid : bssid // ignore: cast_nullable_to_non_nullable
|
||||
as String,createdAt: null == 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 String,password: freezed == password ? _self.password : password // ignore: cast_nullable_to_non_nullable
|
||||
as String?,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?,
|
||||
));
|
||||
}
|
||||
@@ -430,10 +431,10 @@ return $default(_that);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String deviceId, String ssid, String bssid, int createdAt, int? updatedAt)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String deviceIdentificator, String ssid, String bssid, String? password, int? createdAt, int? updatedAt)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _WifiNetworkItemResponseModel() when $default != null:
|
||||
return $default(_that.id,_that.deviceId,_that.ssid,_that.bssid,_that.createdAt,_that.updatedAt);case _:
|
||||
return $default(_that.id,_that.deviceIdentificator,_that.ssid,_that.bssid,_that.password,_that.createdAt,_that.updatedAt);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
@@ -451,10 +452,10 @@ return $default(_that.id,_that.deviceId,_that.ssid,_that.bssid,_that.createdAt,_
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String deviceId, String ssid, String bssid, int createdAt, int? updatedAt) $default,) {final _that = this;
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String deviceIdentificator, String ssid, String bssid, String? password, int? createdAt, int? updatedAt) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _WifiNetworkItemResponseModel():
|
||||
return $default(_that.id,_that.deviceId,_that.ssid,_that.bssid,_that.createdAt,_that.updatedAt);case _:
|
||||
return $default(_that.id,_that.deviceIdentificator,_that.ssid,_that.bssid,_that.password,_that.createdAt,_that.updatedAt);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
@@ -471,10 +472,10 @@ return $default(_that.id,_that.deviceId,_that.ssid,_that.bssid,_that.createdAt,_
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String deviceId, String ssid, String bssid, int createdAt, int? updatedAt)? $default,) {final _that = this;
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String deviceIdentificator, String ssid, String bssid, String? password, int? createdAt, int? updatedAt)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _WifiNetworkItemResponseModel() when $default != null:
|
||||
return $default(_that.id,_that.deviceId,_that.ssid,_that.bssid,_that.createdAt,_that.updatedAt);case _:
|
||||
return $default(_that.id,_that.deviceIdentificator,_that.ssid,_that.bssid,_that.password,_that.createdAt,_that.updatedAt);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
@@ -486,14 +487,15 @@ return $default(_that.id,_that.deviceId,_that.ssid,_that.bssid,_that.createdAt,_
|
||||
@JsonSerializable()
|
||||
|
||||
class _WifiNetworkItemResponseModel implements WifiNetworkItemResponseModel {
|
||||
const _WifiNetworkItemResponseModel({required this.id, required this.deviceId, required this.ssid, required this.bssid, required this.createdAt, this.updatedAt});
|
||||
const _WifiNetworkItemResponseModel({required this.id, this.deviceIdentificator = '', required this.ssid, required this.bssid, this.password, this.createdAt, this.updatedAt});
|
||||
factory _WifiNetworkItemResponseModel.fromJson(Map<String, dynamic> json) => _$WifiNetworkItemResponseModelFromJson(json);
|
||||
|
||||
@override final String id;
|
||||
@override final String deviceId;
|
||||
@override@JsonKey() final String deviceIdentificator;
|
||||
@override final String ssid;
|
||||
@override final String bssid;
|
||||
@override final int createdAt;
|
||||
@override final String? password;
|
||||
@override final int? createdAt;
|
||||
@override final int? updatedAt;
|
||||
|
||||
/// Create a copy of WifiNetworkItemResponseModel
|
||||
@@ -509,16 +511,16 @@ Map<String, dynamic> toJson() {
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _WifiNetworkItemResponseModel&&(identical(other.id, id) || other.id == id)&&(identical(other.deviceId, deviceId) || other.deviceId == deviceId)&&(identical(other.ssid, ssid) || other.ssid == ssid)&&(identical(other.bssid, bssid) || other.bssid == bssid)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt));
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _WifiNetworkItemResponseModel&&(identical(other.id, id) || other.id == id)&&(identical(other.deviceIdentificator, deviceIdentificator) || other.deviceIdentificator == deviceIdentificator)&&(identical(other.ssid, ssid) || other.ssid == ssid)&&(identical(other.bssid, bssid) || other.bssid == bssid)&&(identical(other.password, password) || other.password == password)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,id,deviceId,ssid,bssid,createdAt,updatedAt);
|
||||
int get hashCode => Object.hash(runtimeType,id,deviceIdentificator,ssid,bssid,password,createdAt,updatedAt);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'WifiNetworkItemResponseModel(id: $id, deviceId: $deviceId, ssid: $ssid, bssid: $bssid, createdAt: $createdAt, updatedAt: $updatedAt)';
|
||||
return 'WifiNetworkItemResponseModel(id: $id, deviceIdentificator: $deviceIdentificator, ssid: $ssid, bssid: $bssid, password: $password, createdAt: $createdAt, updatedAt: $updatedAt)';
|
||||
}
|
||||
|
||||
|
||||
@@ -529,7 +531,7 @@ abstract mixin class _$WifiNetworkItemResponseModelCopyWith<$Res> implements $Wi
|
||||
factory _$WifiNetworkItemResponseModelCopyWith(_WifiNetworkItemResponseModel value, $Res Function(_WifiNetworkItemResponseModel) _then) = __$WifiNetworkItemResponseModelCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String id, String deviceId, String ssid, String bssid, int createdAt, int? updatedAt
|
||||
String id, String deviceIdentificator, String ssid, String bssid, String? password, int? createdAt, int? updatedAt
|
||||
});
|
||||
|
||||
|
||||
@@ -546,14 +548,15 @@ class __$WifiNetworkItemResponseModelCopyWithImpl<$Res>
|
||||
|
||||
/// Create a copy of WifiNetworkItemResponseModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? deviceId = null,Object? ssid = null,Object? bssid = null,Object? createdAt = null,Object? updatedAt = freezed,}) {
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? deviceIdentificator = null,Object? ssid = null,Object? bssid = null,Object? password = freezed,Object? createdAt = freezed,Object? updatedAt = freezed,}) {
|
||||
return _then(_WifiNetworkItemResponseModel(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,deviceId: null == deviceId ? _self.deviceId : deviceId // ignore: cast_nullable_to_non_nullable
|
||||
as String,deviceIdentificator: null == deviceIdentificator ? _self.deviceIdentificator : deviceIdentificator // ignore: cast_nullable_to_non_nullable
|
||||
as String,ssid: null == ssid ? _self.ssid : ssid // ignore: cast_nullable_to_non_nullable
|
||||
as String,bssid: null == bssid ? _self.bssid : bssid // ignore: cast_nullable_to_non_nullable
|
||||
as String,createdAt: null == 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 String,password: freezed == password ? _self.password : password // ignore: cast_nullable_to_non_nullable
|
||||
as String?,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?,
|
||||
));
|
||||
}
|
||||
|
||||
@@ -9,12 +9,16 @@ part of 'get_wifi_networks_response_model.dart';
|
||||
_GetWifiNetworksResponseModel _$GetWifiNetworksResponseModelFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _GetWifiNetworksResponseModel(
|
||||
total: (json['total'] as num).toInt(),
|
||||
items: (json['items'] as List<dynamic>)
|
||||
.map(
|
||||
(e) => WifiNetworkItemResponseModel.fromJson(e as Map<String, dynamic>),
|
||||
)
|
||||
.toList(),
|
||||
total: (json['total'] as num?)?.toInt() ?? 0,
|
||||
items:
|
||||
(json['items'] as List<dynamic>?)
|
||||
?.map(
|
||||
(e) => WifiNetworkItemResponseModel.fromJson(
|
||||
e as Map<String, dynamic>,
|
||||
),
|
||||
)
|
||||
.toList() ??
|
||||
const [],
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$GetWifiNetworksResponseModelToJson(
|
||||
@@ -25,10 +29,11 @@ _WifiNetworkItemResponseModel _$WifiNetworkItemResponseModelFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _WifiNetworkItemResponseModel(
|
||||
id: json['id'] as String,
|
||||
deviceId: json['deviceId'] as String,
|
||||
deviceIdentificator: json['deviceIdentificator'] as String? ?? '',
|
||||
ssid: json['ssid'] as String,
|
||||
bssid: json['bssid'] as String,
|
||||
createdAt: (json['createdAt'] as num).toInt(),
|
||||
password: json['password'] as String?,
|
||||
createdAt: (json['createdAt'] as num?)?.toInt(),
|
||||
updatedAt: (json['updatedAt'] as num?)?.toInt(),
|
||||
);
|
||||
|
||||
@@ -36,9 +41,10 @@ Map<String, dynamic> _$WifiNetworkItemResponseModelToJson(
|
||||
_WifiNetworkItemResponseModel instance,
|
||||
) => <String, dynamic>{
|
||||
'id': instance.id,
|
||||
'deviceId': instance.deviceId,
|
||||
'deviceIdentificator': instance.deviceIdentificator,
|
||||
'ssid': instance.ssid,
|
||||
'bssid': instance.bssid,
|
||||
'password': instance.password,
|
||||
'createdAt': instance.createdAt,
|
||||
'updatedAt': instance.updatedAt,
|
||||
};
|
||||
|
||||
@@ -1,51 +1,33 @@
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
import '../../../features/wifi_settings/domain/entities/wifi_network_entity.dart';
|
||||
import '../../domain/repositories/wifi_repository.dart';
|
||||
import '../datasources/wifi_remote_datasource.dart';
|
||||
import '../models/create_wifi_network_request_model.dart';
|
||||
|
||||
class WifiRepositoryImpl implements WifiRepository {
|
||||
WifiRepositoryImpl(this._datasource);
|
||||
|
||||
static const _uuid = Uuid();
|
||||
final WifiRemoteDatasource _datasource;
|
||||
|
||||
@override
|
||||
Future<List<WifiNetworkEntity>> getWifiNetworks({
|
||||
required String deviceId,
|
||||
}) async {
|
||||
final response = await _datasource.getWifiNetworks(deviceId: deviceId);
|
||||
|
||||
return response.items
|
||||
.map(
|
||||
(item) => WifiNetworkEntity(
|
||||
id: item.id,
|
||||
ssid: item.ssid,
|
||||
bssid: item.bssid,
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
}
|
||||
required String deviceIdentificator,
|
||||
}) => _datasource.getWifiNetworks(deviceIdentificator: deviceIdentificator);
|
||||
|
||||
@override
|
||||
Future<void> createWifiNetwork({
|
||||
required String deviceId,
|
||||
required String id,
|
||||
required String deviceIdentificator,
|
||||
required String ssid,
|
||||
required String bssid,
|
||||
}) async {
|
||||
final request = CreateWifiNetworkRequestModel(
|
||||
id: _uuid.v4(),
|
||||
deviceId: deviceId,
|
||||
ssid: ssid,
|
||||
bssid: bssid,
|
||||
);
|
||||
|
||||
await _datasource.createWifiNetwork(request: request);
|
||||
}
|
||||
required String password,
|
||||
}) => _datasource.createWifiNetwork(
|
||||
id: id,
|
||||
deviceIdentificator: deviceIdentificator,
|
||||
ssid: ssid,
|
||||
bssid: bssid,
|
||||
password: password,
|
||||
);
|
||||
|
||||
@override
|
||||
Future<void> deleteWifiNetwork({required String networkId}) {
|
||||
return _datasource.deleteWifiNetwork(networkId: networkId);
|
||||
}
|
||||
Future<void> deleteWifiNetwork({required String networkId}) =>
|
||||
_datasource.deleteWifiNetwork(networkId: networkId);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
import 'package:settings/src/features/wifi_settings/domain/entities/wifi_network_entity.dart';
|
||||
|
||||
abstract class WifiRepository {
|
||||
Future<List<WifiNetworkEntity>> getWifiNetworks({required String deviceId});
|
||||
Future<List<WifiNetworkEntity>> getWifiNetworks({
|
||||
required String deviceIdentificator,
|
||||
});
|
||||
|
||||
Future<void> createWifiNetwork({
|
||||
required String deviceId,
|
||||
required String id,
|
||||
required String deviceIdentificator,
|
||||
required String ssid,
|
||||
required String bssid,
|
||||
required String password,
|
||||
});
|
||||
|
||||
Future<void> deleteWifiNetwork({required String networkId});
|
||||
|
||||
@@ -15,6 +15,12 @@ class SettingsScreen extends ConsumerWidget {
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final theme = ref.watch(themePortProvider);
|
||||
final color = theme.getColorFor(ThemeCode.legacyPrimary);
|
||||
final hasWifi = ref.watch(
|
||||
selectedDeviceProvider.select((d) {
|
||||
final types = d.value?.capabilities?.commands;
|
||||
return types?.types.contains('WIFI_SEARCH') ?? false;
|
||||
}),
|
||||
);
|
||||
|
||||
return LegacyPageLayout(
|
||||
theme: theme,
|
||||
@@ -101,14 +107,15 @@ class SettingsScreen extends ConsumerWidget {
|
||||
text: I18n.sound,
|
||||
color: color,
|
||||
),
|
||||
// _item(
|
||||
// context,
|
||||
// onPressed: () =>
|
||||
// navigationContract.pushTo(AppRoutes.wifiSettings),
|
||||
// icon: Icons.wifi_find_outlined,
|
||||
// text: I18n.wifiSettings,
|
||||
// color: color,
|
||||
// ),
|
||||
if (hasWifi)
|
||||
_item(
|
||||
context,
|
||||
onPressed: () =>
|
||||
navigationContract.pushTo(AppRoutes.wifiSettings),
|
||||
icon: Icons.wifi_find_outlined,
|
||||
text: I18n.wifiSettings,
|
||||
color: color,
|
||||
),
|
||||
// _item(
|
||||
// context,
|
||||
// onPressed: () =>
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'scanned_wifi_network.freezed.dart';
|
||||
|
||||
@freezed
|
||||
abstract class ScannedWifiNetwork with _$ScannedWifiNetwork {
|
||||
const factory ScannedWifiNetwork({
|
||||
required String ssid,
|
||||
required String bssid,
|
||||
}) = _ScannedWifiNetwork;
|
||||
}
|
||||
@@ -0,0 +1,274 @@
|
||||
// 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 'scanned_wifi_network.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$ScannedWifiNetwork {
|
||||
|
||||
String get ssid; String get bssid;
|
||||
/// Create a copy of ScannedWifiNetwork
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$ScannedWifiNetworkCopyWith<ScannedWifiNetwork> get copyWith => _$ScannedWifiNetworkCopyWithImpl<ScannedWifiNetwork>(this as ScannedWifiNetwork, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is ScannedWifiNetwork&&(identical(other.ssid, ssid) || other.ssid == ssid)&&(identical(other.bssid, bssid) || other.bssid == bssid));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,ssid,bssid);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ScannedWifiNetwork(ssid: $ssid, bssid: $bssid)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $ScannedWifiNetworkCopyWith<$Res> {
|
||||
factory $ScannedWifiNetworkCopyWith(ScannedWifiNetwork value, $Res Function(ScannedWifiNetwork) _then) = _$ScannedWifiNetworkCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String ssid, String bssid
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$ScannedWifiNetworkCopyWithImpl<$Res>
|
||||
implements $ScannedWifiNetworkCopyWith<$Res> {
|
||||
_$ScannedWifiNetworkCopyWithImpl(this._self, this._then);
|
||||
|
||||
final ScannedWifiNetwork _self;
|
||||
final $Res Function(ScannedWifiNetwork) _then;
|
||||
|
||||
/// Create a copy of ScannedWifiNetwork
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? ssid = null,Object? bssid = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
ssid: null == ssid ? _self.ssid : ssid // ignore: cast_nullable_to_non_nullable
|
||||
as String,bssid: null == bssid ? _self.bssid : bssid // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [ScannedWifiNetwork].
|
||||
extension ScannedWifiNetworkPatterns on ScannedWifiNetwork {
|
||||
/// 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( _ScannedWifiNetwork value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _ScannedWifiNetwork() 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( _ScannedWifiNetwork value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _ScannedWifiNetwork():
|
||||
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( _ScannedWifiNetwork value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _ScannedWifiNetwork() 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 ssid, String bssid)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _ScannedWifiNetwork() when $default != null:
|
||||
return $default(_that.ssid,_that.bssid);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 ssid, String bssid) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _ScannedWifiNetwork():
|
||||
return $default(_that.ssid,_that.bssid);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 ssid, String bssid)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _ScannedWifiNetwork() when $default != null:
|
||||
return $default(_that.ssid,_that.bssid);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _ScannedWifiNetwork implements ScannedWifiNetwork {
|
||||
const _ScannedWifiNetwork({required this.ssid, required this.bssid});
|
||||
|
||||
|
||||
@override final String ssid;
|
||||
@override final String bssid;
|
||||
|
||||
/// Create a copy of ScannedWifiNetwork
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$ScannedWifiNetworkCopyWith<_ScannedWifiNetwork> get copyWith => __$ScannedWifiNetworkCopyWithImpl<_ScannedWifiNetwork>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _ScannedWifiNetwork&&(identical(other.ssid, ssid) || other.ssid == ssid)&&(identical(other.bssid, bssid) || other.bssid == bssid));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,ssid,bssid);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ScannedWifiNetwork(ssid: $ssid, bssid: $bssid)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$ScannedWifiNetworkCopyWith<$Res> implements $ScannedWifiNetworkCopyWith<$Res> {
|
||||
factory _$ScannedWifiNetworkCopyWith(_ScannedWifiNetwork value, $Res Function(_ScannedWifiNetwork) _then) = __$ScannedWifiNetworkCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String ssid, String bssid
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$ScannedWifiNetworkCopyWithImpl<$Res>
|
||||
implements _$ScannedWifiNetworkCopyWith<$Res> {
|
||||
__$ScannedWifiNetworkCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _ScannedWifiNetwork _self;
|
||||
final $Res Function(_ScannedWifiNetwork) _then;
|
||||
|
||||
/// Create a copy of ScannedWifiNetwork
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? ssid = null,Object? bssid = null,}) {
|
||||
return _then(_ScannedWifiNetwork(
|
||||
ssid: null == ssid ? _self.ssid : ssid // ignore: cast_nullable_to_non_nullable
|
||||
as String,bssid: null == bssid ? _self.bssid : bssid // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -8,5 +8,8 @@ abstract class WifiNetworkEntity with _$WifiNetworkEntity {
|
||||
required String id,
|
||||
required String ssid,
|
||||
required String bssid,
|
||||
String? password,
|
||||
String? deviceIdentificator,
|
||||
int? createdAt,
|
||||
}) = _WifiNetworkEntity;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$WifiNetworkEntity {
|
||||
|
||||
String get id; String get ssid; String get bssid;
|
||||
String get id; String get ssid; String get bssid; String? get password; String? get deviceIdentificator; int? get createdAt;
|
||||
/// Create a copy of WifiNetworkEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@@ -25,16 +25,16 @@ $WifiNetworkEntityCopyWith<WifiNetworkEntity> get copyWith => _$WifiNetworkEntit
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is WifiNetworkEntity&&(identical(other.id, id) || other.id == id)&&(identical(other.ssid, ssid) || other.ssid == ssid)&&(identical(other.bssid, bssid) || other.bssid == bssid));
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is WifiNetworkEntity&&(identical(other.id, id) || other.id == id)&&(identical(other.ssid, ssid) || other.ssid == ssid)&&(identical(other.bssid, bssid) || other.bssid == bssid)&&(identical(other.password, password) || other.password == password)&&(identical(other.deviceIdentificator, deviceIdentificator) || other.deviceIdentificator == deviceIdentificator)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,id,ssid,bssid);
|
||||
int get hashCode => Object.hash(runtimeType,id,ssid,bssid,password,deviceIdentificator,createdAt);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'WifiNetworkEntity(id: $id, ssid: $ssid, bssid: $bssid)';
|
||||
return 'WifiNetworkEntity(id: $id, ssid: $ssid, bssid: $bssid, password: $password, deviceIdentificator: $deviceIdentificator, createdAt: $createdAt)';
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ abstract mixin class $WifiNetworkEntityCopyWith<$Res> {
|
||||
factory $WifiNetworkEntityCopyWith(WifiNetworkEntity value, $Res Function(WifiNetworkEntity) _then) = _$WifiNetworkEntityCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String id, String ssid, String bssid
|
||||
String id, String ssid, String bssid, String? password, String? deviceIdentificator, int? createdAt
|
||||
});
|
||||
|
||||
|
||||
@@ -62,12 +62,15 @@ class _$WifiNetworkEntityCopyWithImpl<$Res>
|
||||
|
||||
/// Create a copy of WifiNetworkEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? ssid = null,Object? bssid = null,}) {
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? ssid = null,Object? bssid = null,Object? password = freezed,Object? deviceIdentificator = freezed,Object? createdAt = freezed,}) {
|
||||
return _then(_self.copyWith(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,ssid: null == ssid ? _self.ssid : ssid // ignore: cast_nullable_to_non_nullable
|
||||
as String,bssid: null == bssid ? _self.bssid : bssid // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
as String,password: freezed == password ? _self.password : password // ignore: cast_nullable_to_non_nullable
|
||||
as String?,deviceIdentificator: freezed == deviceIdentificator ? _self.deviceIdentificator : deviceIdentificator // ignore: cast_nullable_to_non_nullable
|
||||
as String?,createdAt: freezed == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as int?,
|
||||
));
|
||||
}
|
||||
|
||||
@@ -152,10 +155,10 @@ return $default(_that);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String ssid, String bssid)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String ssid, String bssid, String? password, String? deviceIdentificator, int? createdAt)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _WifiNetworkEntity() when $default != null:
|
||||
return $default(_that.id,_that.ssid,_that.bssid);case _:
|
||||
return $default(_that.id,_that.ssid,_that.bssid,_that.password,_that.deviceIdentificator,_that.createdAt);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
@@ -173,10 +176,10 @@ return $default(_that.id,_that.ssid,_that.bssid);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String ssid, String bssid) $default,) {final _that = this;
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String ssid, String bssid, String? password, String? deviceIdentificator, int? createdAt) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _WifiNetworkEntity():
|
||||
return $default(_that.id,_that.ssid,_that.bssid);case _:
|
||||
return $default(_that.id,_that.ssid,_that.bssid,_that.password,_that.deviceIdentificator,_that.createdAt);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
@@ -193,10 +196,10 @@ return $default(_that.id,_that.ssid,_that.bssid);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String ssid, String bssid)? $default,) {final _that = this;
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String ssid, String bssid, String? password, String? deviceIdentificator, int? createdAt)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _WifiNetworkEntity() when $default != null:
|
||||
return $default(_that.id,_that.ssid,_that.bssid);case _:
|
||||
return $default(_that.id,_that.ssid,_that.bssid,_that.password,_that.deviceIdentificator,_that.createdAt);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
@@ -208,12 +211,15 @@ return $default(_that.id,_that.ssid,_that.bssid);case _:
|
||||
|
||||
|
||||
class _WifiNetworkEntity implements WifiNetworkEntity {
|
||||
const _WifiNetworkEntity({required this.id, required this.ssid, required this.bssid});
|
||||
const _WifiNetworkEntity({required this.id, required this.ssid, required this.bssid, this.password, this.deviceIdentificator, this.createdAt});
|
||||
|
||||
|
||||
@override final String id;
|
||||
@override final String ssid;
|
||||
@override final String bssid;
|
||||
@override final String? password;
|
||||
@override final String? deviceIdentificator;
|
||||
@override final int? createdAt;
|
||||
|
||||
/// Create a copy of WifiNetworkEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@@ -225,16 +231,16 @@ _$WifiNetworkEntityCopyWith<_WifiNetworkEntity> get copyWith => __$WifiNetworkEn
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _WifiNetworkEntity&&(identical(other.id, id) || other.id == id)&&(identical(other.ssid, ssid) || other.ssid == ssid)&&(identical(other.bssid, bssid) || other.bssid == bssid));
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _WifiNetworkEntity&&(identical(other.id, id) || other.id == id)&&(identical(other.ssid, ssid) || other.ssid == ssid)&&(identical(other.bssid, bssid) || other.bssid == bssid)&&(identical(other.password, password) || other.password == password)&&(identical(other.deviceIdentificator, deviceIdentificator) || other.deviceIdentificator == deviceIdentificator)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,id,ssid,bssid);
|
||||
int get hashCode => Object.hash(runtimeType,id,ssid,bssid,password,deviceIdentificator,createdAt);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'WifiNetworkEntity(id: $id, ssid: $ssid, bssid: $bssid)';
|
||||
return 'WifiNetworkEntity(id: $id, ssid: $ssid, bssid: $bssid, password: $password, deviceIdentificator: $deviceIdentificator, createdAt: $createdAt)';
|
||||
}
|
||||
|
||||
|
||||
@@ -245,7 +251,7 @@ abstract mixin class _$WifiNetworkEntityCopyWith<$Res> implements $WifiNetworkEn
|
||||
factory _$WifiNetworkEntityCopyWith(_WifiNetworkEntity value, $Res Function(_WifiNetworkEntity) _then) = __$WifiNetworkEntityCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String id, String ssid, String bssid
|
||||
String id, String ssid, String bssid, String? password, String? deviceIdentificator, int? createdAt
|
||||
});
|
||||
|
||||
|
||||
@@ -262,12 +268,15 @@ class __$WifiNetworkEntityCopyWithImpl<$Res>
|
||||
|
||||
/// Create a copy of WifiNetworkEntity
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? ssid = null,Object? bssid = null,}) {
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? ssid = null,Object? bssid = null,Object? password = freezed,Object? deviceIdentificator = freezed,Object? createdAt = freezed,}) {
|
||||
return _then(_WifiNetworkEntity(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,ssid: null == ssid ? _self.ssid : ssid // ignore: cast_nullable_to_non_nullable
|
||||
as String,bssid: null == bssid ? _self.bssid : bssid // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
as String,password: freezed == password ? _self.password : password // ignore: cast_nullable_to_non_nullable
|
||||
as String?,deviceIdentificator: freezed == deviceIdentificator ? _self.deviceIdentificator : deviceIdentificator // ignore: cast_nullable_to_non_nullable
|
||||
as String?,createdAt: freezed == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as int?,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:legacy_shared/legacy_shared.dart';
|
||||
import 'package:sf_localizations/sf_localizations.dart';
|
||||
import 'package:sf_infrastructure/sf_infrastructure.dart';
|
||||
import 'package:sf_tracking/sf_tracking.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
import '../../../../core/domain/repositories/wifi_repository.dart';
|
||||
import '../../../../core/providers/wifi_repository_provider.dart';
|
||||
import '../../domain/entities/scanned_wifi_network.dart';
|
||||
import '../../domain/entities/wifi_network_entity.dart';
|
||||
import 'wifi_settings_view_state.dart';
|
||||
|
||||
final wifiSettingsViewModelProvider =
|
||||
@@ -16,90 +20,260 @@ final wifiSettingsViewModelProvider =
|
||||
|
||||
class WifiSettingsViewModel extends Notifier<WifiSettingsViewState> {
|
||||
late final WifiRepository _repository;
|
||||
late final CommandsRepository _commands;
|
||||
late final SfTrackingRepository _tracking;
|
||||
late final WebSocketService _webSocket;
|
||||
StreamSubscription<WebSocketEvent>? _webSocketSubscription;
|
||||
Timer? _scanCountdown;
|
||||
Timer? _currentNetworkTimeout;
|
||||
|
||||
static const _scanDurationSeconds = 30;
|
||||
|
||||
@override
|
||||
WifiSettingsViewState build() {
|
||||
_repository = ref.read(wifiRepositoryProvider);
|
||||
_commands = ref.read(commandsRepositoryProvider);
|
||||
_tracking = ref.read(sfTrackingProvider);
|
||||
_webSocket = GetIt.I<WebSocketService>();
|
||||
|
||||
_webSocketSubscription = _webSocket.events.listen(_onWebSocketEvent);
|
||||
ref.onDispose(() {
|
||||
_webSocketSubscription?.cancel();
|
||||
_scanCountdown?.cancel();
|
||||
_currentNetworkTimeout?.cancel();
|
||||
});
|
||||
|
||||
Future.microtask(_load);
|
||||
return const WifiSettingsViewState();
|
||||
}
|
||||
|
||||
Future<void> _load() async {
|
||||
try {
|
||||
final device = ref.read(selectedDeviceProvider).value;
|
||||
if (device == null) return;
|
||||
String? get _identificator =>
|
||||
ref.read(selectedDeviceProvider).value?.identificator;
|
||||
|
||||
final networks = await _repository.getWifiNetworks(deviceId: device.id);
|
||||
state = state.copyWith(networks: networks, isLoading: false);
|
||||
} catch (e) {
|
||||
void _onWebSocketEvent(WebSocketEvent event) {
|
||||
switch (event) {
|
||||
case WifiEvent():
|
||||
_currentNetworkTimeout?.cancel();
|
||||
final network = WifiNetworkEntity(
|
||||
id: '',
|
||||
ssid: event.ssid,
|
||||
bssid: event.bssid,
|
||||
password: event.password,
|
||||
);
|
||||
state = state.copyWith(
|
||||
currentNetwork: network,
|
||||
isConnecting: false,
|
||||
isLoadingCurrentNetwork: false,
|
||||
);
|
||||
case WifiSearchEvent():
|
||||
_scanCountdown?.cancel();
|
||||
final networks = event.wifis
|
||||
.map(
|
||||
(wifi) => ScannedWifiNetwork(
|
||||
ssid: wifi['ssid'] as String? ?? '',
|
||||
bssid: wifi['bssid'] as String? ?? '',
|
||||
),
|
||||
)
|
||||
.where((network) => network.ssid.isNotEmpty)
|
||||
.toList();
|
||||
state = state.copyWith(
|
||||
availableNetworks: networks,
|
||||
isScanning: false,
|
||||
scanSecondsRemaining: 0,
|
||||
);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _load() async {
|
||||
final identificator = _identificator;
|
||||
if (identificator == null) {
|
||||
state = state.copyWith(isLoading: false);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
final networks = await _repository.getWifiNetworks(
|
||||
deviceIdentificator: identificator,
|
||||
);
|
||||
if (!ref.mounted) return;
|
||||
|
||||
state = state.copyWith(
|
||||
savedNetworks: networks,
|
||||
isLoading: false,
|
||||
isLoadingCurrentNetwork: true,
|
||||
);
|
||||
|
||||
unawaited(
|
||||
_commands
|
||||
.send(
|
||||
request: SendCommandRequestModel(
|
||||
device: identificator,
|
||||
command: DeviceCommand.wifiCurrent,
|
||||
),
|
||||
)
|
||||
.catchError((_) {
|
||||
if (ref.mounted) {
|
||||
state = state.copyWith(isLoadingCurrentNetwork: false);
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
_currentNetworkTimeout?.cancel();
|
||||
_currentNetworkTimeout = Timer(const Duration(seconds: 15), () {
|
||||
if (!ref.mounted) return;
|
||||
if (state.isLoadingCurrentNetwork) {
|
||||
state = state.copyWith(isLoadingCurrentNetwork: false);
|
||||
}
|
||||
});
|
||||
} catch (_) {
|
||||
if (!ref.mounted) return;
|
||||
state = state.copyWith(
|
||||
isLoading: false,
|
||||
errorMessage: formatErrorMessage(e),
|
||||
error: WifiSettingsError.loadFailed,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> addNetwork({required String ssid, required String bssid}) async {
|
||||
state = state.copyWith(isSaving: true, errorMessage: '');
|
||||
Future<void> scanNetworks() async {
|
||||
final identificator = _identificator;
|
||||
if (identificator == null) return;
|
||||
|
||||
state = state.copyWith(
|
||||
isScanning: true,
|
||||
scanSecondsRemaining: _scanDurationSeconds,
|
||||
error: null,
|
||||
);
|
||||
|
||||
try {
|
||||
final device = ref.read(selectedDeviceProvider).value;
|
||||
if (device == null) return;
|
||||
|
||||
await _repository.createWifiNetwork(
|
||||
deviceId: device.id,
|
||||
ssid: ssid,
|
||||
bssid: bssid,
|
||||
await _commands.send(
|
||||
request: SendCommandRequestModel(
|
||||
device: identificator,
|
||||
command: DeviceCommand.wifiSearch,
|
||||
),
|
||||
);
|
||||
|
||||
final networks = await _repository.getWifiNetworks(deviceId: device.id);
|
||||
_scanCountdown?.cancel();
|
||||
|
||||
_scanCountdown = Timer.periodic(const Duration(seconds: 1), (_) {
|
||||
if (!ref.mounted) {
|
||||
_scanCountdown?.cancel();
|
||||
return;
|
||||
}
|
||||
final remaining = state.scanSecondsRemaining - 1;
|
||||
if (remaining <= 0) {
|
||||
_scanCountdown?.cancel();
|
||||
if (state.isScanning) {
|
||||
state = state.copyWith(
|
||||
isScanning: false,
|
||||
scanSecondsRemaining: 0,
|
||||
error: WifiSettingsError.scanFailed,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
state = state.copyWith(scanSecondsRemaining: remaining);
|
||||
}
|
||||
});
|
||||
} catch (_) {
|
||||
if (!ref.mounted) return;
|
||||
_scanCountdown?.cancel();
|
||||
state = state.copyWith(
|
||||
isScanning: false,
|
||||
scanSecondsRemaining: 0,
|
||||
error: WifiSettingsError.scanFailed,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> connectAndSave({
|
||||
required String ssid,
|
||||
required String bssid,
|
||||
required String password,
|
||||
}) async {
|
||||
final identificator = _identificator;
|
||||
if (identificator == null) return;
|
||||
|
||||
state = state.copyWith(isConnecting: true, error: null, success: null);
|
||||
|
||||
try {
|
||||
await _commands.send(
|
||||
request: SendCommandRequestModel(
|
||||
device: identificator,
|
||||
command: DeviceCommand.setWifi,
|
||||
data: {'ssid': ssid, 'bssid': bssid, 'password': password},
|
||||
),
|
||||
);
|
||||
|
||||
final id = const Uuid().v4();
|
||||
await _repository.createWifiNetwork(
|
||||
id: id,
|
||||
deviceIdentificator: identificator,
|
||||
ssid: ssid,
|
||||
bssid: bssid,
|
||||
password: password,
|
||||
);
|
||||
if (!ref.mounted) return;
|
||||
|
||||
final networks = await _repository.getWifiNetworks(
|
||||
deviceIdentificator: identificator,
|
||||
);
|
||||
if (!ref.mounted) return;
|
||||
|
||||
unawaited(_tracking.legacySettingsWifiAdded(totalCount: networks.length));
|
||||
|
||||
state = state.copyWith(
|
||||
networks: networks,
|
||||
isSaving: false,
|
||||
successMessage: I18n.wifiNetworkAdded,
|
||||
savedNetworks: networks,
|
||||
isConnecting: false,
|
||||
success: WifiSettingsSuccess.networkSaved,
|
||||
);
|
||||
} catch (e) {
|
||||
} catch (_) {
|
||||
if (!ref.mounted) return;
|
||||
state = state.copyWith(
|
||||
isSaving: false,
|
||||
errorMessage: formatErrorMessage(e),
|
||||
isConnecting: false,
|
||||
error: WifiSettingsError.saveFailed,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> removeNetwork(String networkId) async {
|
||||
state = state.copyWith(isSaving: true, errorMessage: '');
|
||||
final identificator = _identificator;
|
||||
if (identificator == null) return;
|
||||
|
||||
state = state.copyWith(isSaving: true, error: null, success: null);
|
||||
|
||||
try {
|
||||
final device = ref.read(selectedDeviceProvider).value;
|
||||
if (device == null) return;
|
||||
|
||||
await _repository.deleteWifiNetwork(networkId: networkId);
|
||||
if (!ref.mounted) return;
|
||||
|
||||
final networks = await _repository.getWifiNetworks(deviceId: device.id);
|
||||
final networks = await _repository.getWifiNetworks(
|
||||
deviceIdentificator: identificator,
|
||||
);
|
||||
if (!ref.mounted) return;
|
||||
|
||||
unawaited(
|
||||
_tracking.legacySettingsWifiRemoved(totalCount: networks.length),
|
||||
);
|
||||
|
||||
state = state.copyWith(
|
||||
networks: networks,
|
||||
savedNetworks: networks,
|
||||
isSaving: false,
|
||||
successMessage: I18n.wifiNetworkRemoved,
|
||||
success: WifiSettingsSuccess.networkDeleted,
|
||||
);
|
||||
} catch (e) {
|
||||
} catch (_) {
|
||||
if (!ref.mounted) return;
|
||||
state = state.copyWith(
|
||||
isSaving: false,
|
||||
errorMessage: formatErrorMessage(e),
|
||||
error: WifiSettingsError.deleteFailed,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void clearError() {
|
||||
if (state.error != null) state = state.copyWith(error: null);
|
||||
}
|
||||
|
||||
void clearSuccess() {
|
||||
state = state.copyWith(successMessage: '');
|
||||
if (state.success != null) state = state.copyWith(success: null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,27 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
import '../../domain/entities/scanned_wifi_network.dart';
|
||||
import '../../domain/entities/wifi_network_entity.dart';
|
||||
|
||||
part 'wifi_settings_view_state.freezed.dart';
|
||||
|
||||
enum WifiSettingsError { loadFailed, scanFailed, connectFailed, saveFailed, deleteFailed }
|
||||
|
||||
enum WifiSettingsSuccess { networkSaved, networkDeleted, connected }
|
||||
|
||||
@freezed
|
||||
abstract class WifiSettingsViewState with _$WifiSettingsViewState {
|
||||
const factory WifiSettingsViewState({
|
||||
@Default([]) List<WifiNetworkEntity> networks,
|
||||
@Default([]) List<WifiNetworkEntity> savedNetworks,
|
||||
@Default([]) List<ScannedWifiNetwork> availableNetworks,
|
||||
WifiNetworkEntity? currentNetwork,
|
||||
@Default(true) bool isLoading,
|
||||
@Default(false) bool isLoadingCurrentNetwork,
|
||||
@Default(false) bool isScanning,
|
||||
@Default(0) int scanSecondsRemaining,
|
||||
@Default(false) bool isSaving,
|
||||
@Default('') String successMessage,
|
||||
@Default('') String errorMessage,
|
||||
@Default(false) bool isConnecting,
|
||||
WifiSettingsError? error,
|
||||
WifiSettingsSuccess? success,
|
||||
}) = _WifiSettingsViewState;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$WifiSettingsViewState {
|
||||
|
||||
List<WifiNetworkEntity> get networks; bool get isLoading; bool get isSaving; String get successMessage; String get errorMessage;
|
||||
List<WifiNetworkEntity> get savedNetworks; List<ScannedWifiNetwork> get availableNetworks; WifiNetworkEntity? get currentNetwork; bool get isLoading; bool get isLoadingCurrentNetwork; bool get isScanning; int get scanSecondsRemaining; bool get isSaving; bool get isConnecting; WifiSettingsError? get error; WifiSettingsSuccess? get success;
|
||||
/// Create a copy of WifiSettingsViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@@ -25,16 +25,16 @@ $WifiSettingsViewStateCopyWith<WifiSettingsViewState> get copyWith => _$WifiSett
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is WifiSettingsViewState&&const DeepCollectionEquality().equals(other.networks, networks)&&(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 WifiSettingsViewState&&const DeepCollectionEquality().equals(other.savedNetworks, savedNetworks)&&const DeepCollectionEquality().equals(other.availableNetworks, availableNetworks)&&(identical(other.currentNetwork, currentNetwork) || other.currentNetwork == currentNetwork)&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.isLoadingCurrentNetwork, isLoadingCurrentNetwork) || other.isLoadingCurrentNetwork == isLoadingCurrentNetwork)&&(identical(other.isScanning, isScanning) || other.isScanning == isScanning)&&(identical(other.scanSecondsRemaining, scanSecondsRemaining) || other.scanSecondsRemaining == scanSecondsRemaining)&&(identical(other.isSaving, isSaving) || other.isSaving == isSaving)&&(identical(other.isConnecting, isConnecting) || other.isConnecting == isConnecting)&&(identical(other.error, error) || other.error == error)&&(identical(other.success, success) || other.success == success));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(networks),isLoading,isSaving,successMessage,errorMessage);
|
||||
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(savedNetworks),const DeepCollectionEquality().hash(availableNetworks),currentNetwork,isLoading,isLoadingCurrentNetwork,isScanning,scanSecondsRemaining,isSaving,isConnecting,error,success);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'WifiSettingsViewState(networks: $networks, isLoading: $isLoading, isSaving: $isSaving, successMessage: $successMessage, errorMessage: $errorMessage)';
|
||||
return 'WifiSettingsViewState(savedNetworks: $savedNetworks, availableNetworks: $availableNetworks, currentNetwork: $currentNetwork, isLoading: $isLoading, isLoadingCurrentNetwork: $isLoadingCurrentNetwork, isScanning: $isScanning, scanSecondsRemaining: $scanSecondsRemaining, isSaving: $isSaving, isConnecting: $isConnecting, error: $error, success: $success)';
|
||||
}
|
||||
|
||||
|
||||
@@ -45,11 +45,11 @@ abstract mixin class $WifiSettingsViewStateCopyWith<$Res> {
|
||||
factory $WifiSettingsViewStateCopyWith(WifiSettingsViewState value, $Res Function(WifiSettingsViewState) _then) = _$WifiSettingsViewStateCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
List<WifiNetworkEntity> networks, bool isLoading, bool isSaving, String successMessage, String errorMessage
|
||||
List<WifiNetworkEntity> savedNetworks, List<ScannedWifiNetwork> availableNetworks, WifiNetworkEntity? currentNetwork, bool isLoading, bool isLoadingCurrentNetwork, bool isScanning, int scanSecondsRemaining, bool isSaving, bool isConnecting, WifiSettingsError? error, WifiSettingsSuccess? success
|
||||
});
|
||||
|
||||
|
||||
|
||||
$WifiNetworkEntityCopyWith<$Res>? get currentNetwork;
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
@@ -62,17 +62,35 @@ class _$WifiSettingsViewStateCopyWithImpl<$Res>
|
||||
|
||||
/// Create a copy of WifiSettingsViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? networks = null,Object? isLoading = null,Object? isSaving = null,Object? successMessage = null,Object? errorMessage = null,}) {
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? savedNetworks = null,Object? availableNetworks = null,Object? currentNetwork = freezed,Object? isLoading = null,Object? isLoadingCurrentNetwork = null,Object? isScanning = null,Object? scanSecondsRemaining = null,Object? isSaving = null,Object? isConnecting = null,Object? error = freezed,Object? success = freezed,}) {
|
||||
return _then(_self.copyWith(
|
||||
networks: null == networks ? _self.networks : networks // ignore: cast_nullable_to_non_nullable
|
||||
as List<WifiNetworkEntity>,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,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,
|
||||
savedNetworks: null == savedNetworks ? _self.savedNetworks : savedNetworks // ignore: cast_nullable_to_non_nullable
|
||||
as List<WifiNetworkEntity>,availableNetworks: null == availableNetworks ? _self.availableNetworks : availableNetworks // ignore: cast_nullable_to_non_nullable
|
||||
as List<ScannedWifiNetwork>,currentNetwork: freezed == currentNetwork ? _self.currentNetwork : currentNetwork // ignore: cast_nullable_to_non_nullable
|
||||
as WifiNetworkEntity?,isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable
|
||||
as bool,isLoadingCurrentNetwork: null == isLoadingCurrentNetwork ? _self.isLoadingCurrentNetwork : isLoadingCurrentNetwork // ignore: cast_nullable_to_non_nullable
|
||||
as bool,isScanning: null == isScanning ? _self.isScanning : isScanning // ignore: cast_nullable_to_non_nullable
|
||||
as bool,scanSecondsRemaining: null == scanSecondsRemaining ? _self.scanSecondsRemaining : scanSecondsRemaining // ignore: cast_nullable_to_non_nullable
|
||||
as int,isSaving: null == isSaving ? _self.isSaving : isSaving // ignore: cast_nullable_to_non_nullable
|
||||
as bool,isConnecting: null == isConnecting ? _self.isConnecting : isConnecting // ignore: cast_nullable_to_non_nullable
|
||||
as bool,error: freezed == error ? _self.error : error // ignore: cast_nullable_to_non_nullable
|
||||
as WifiSettingsError?,success: freezed == success ? _self.success : success // ignore: cast_nullable_to_non_nullable
|
||||
as WifiSettingsSuccess?,
|
||||
));
|
||||
}
|
||||
/// Create a copy of WifiSettingsViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$WifiNetworkEntityCopyWith<$Res>? get currentNetwork {
|
||||
if (_self.currentNetwork == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $WifiNetworkEntityCopyWith<$Res>(_self.currentNetwork!, (value) {
|
||||
return _then(_self.copyWith(currentNetwork: value));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -154,10 +172,10 @@ return $default(_that);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( List<WifiNetworkEntity> networks, bool isLoading, bool isSaving, String successMessage, String errorMessage)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( List<WifiNetworkEntity> savedNetworks, List<ScannedWifiNetwork> availableNetworks, WifiNetworkEntity? currentNetwork, bool isLoading, bool isLoadingCurrentNetwork, bool isScanning, int scanSecondsRemaining, bool isSaving, bool isConnecting, WifiSettingsError? error, WifiSettingsSuccess? success)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _WifiSettingsViewState() when $default != null:
|
||||
return $default(_that.networks,_that.isLoading,_that.isSaving,_that.successMessage,_that.errorMessage);case _:
|
||||
return $default(_that.savedNetworks,_that.availableNetworks,_that.currentNetwork,_that.isLoading,_that.isLoadingCurrentNetwork,_that.isScanning,_that.scanSecondsRemaining,_that.isSaving,_that.isConnecting,_that.error,_that.success);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
@@ -175,10 +193,10 @@ return $default(_that.networks,_that.isLoading,_that.isSaving,_that.successMessa
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( List<WifiNetworkEntity> networks, bool isLoading, bool isSaving, String successMessage, String errorMessage) $default,) {final _that = this;
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( List<WifiNetworkEntity> savedNetworks, List<ScannedWifiNetwork> availableNetworks, WifiNetworkEntity? currentNetwork, bool isLoading, bool isLoadingCurrentNetwork, bool isScanning, int scanSecondsRemaining, bool isSaving, bool isConnecting, WifiSettingsError? error, WifiSettingsSuccess? success) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _WifiSettingsViewState():
|
||||
return $default(_that.networks,_that.isLoading,_that.isSaving,_that.successMessage,_that.errorMessage);case _:
|
||||
return $default(_that.savedNetworks,_that.availableNetworks,_that.currentNetwork,_that.isLoading,_that.isLoadingCurrentNetwork,_that.isScanning,_that.scanSecondsRemaining,_that.isSaving,_that.isConnecting,_that.error,_that.success);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
@@ -195,10 +213,10 @@ return $default(_that.networks,_that.isLoading,_that.isSaving,_that.successMessa
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( List<WifiNetworkEntity> networks, bool isLoading, bool isSaving, String successMessage, String errorMessage)? $default,) {final _that = this;
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( List<WifiNetworkEntity> savedNetworks, List<ScannedWifiNetwork> availableNetworks, WifiNetworkEntity? currentNetwork, bool isLoading, bool isLoadingCurrentNetwork, bool isScanning, int scanSecondsRemaining, bool isSaving, bool isConnecting, WifiSettingsError? error, WifiSettingsSuccess? success)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _WifiSettingsViewState() when $default != null:
|
||||
return $default(_that.networks,_that.isLoading,_that.isSaving,_that.successMessage,_that.errorMessage);case _:
|
||||
return $default(_that.savedNetworks,_that.availableNetworks,_that.currentNetwork,_that.isLoading,_that.isLoadingCurrentNetwork,_that.isScanning,_that.scanSecondsRemaining,_that.isSaving,_that.isConnecting,_that.error,_that.success);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
@@ -210,20 +228,32 @@ return $default(_that.networks,_that.isLoading,_that.isSaving,_that.successMessa
|
||||
|
||||
|
||||
class _WifiSettingsViewState implements WifiSettingsViewState {
|
||||
const _WifiSettingsViewState({final List<WifiNetworkEntity> networks = const [], this.isLoading = true, this.isSaving = false, this.successMessage = '', this.errorMessage = ''}): _networks = networks;
|
||||
const _WifiSettingsViewState({final List<WifiNetworkEntity> savedNetworks = const [], final List<ScannedWifiNetwork> availableNetworks = const [], this.currentNetwork, this.isLoading = true, this.isLoadingCurrentNetwork = false, this.isScanning = false, this.scanSecondsRemaining = 0, this.isSaving = false, this.isConnecting = false, this.error, this.success}): _savedNetworks = savedNetworks,_availableNetworks = availableNetworks;
|
||||
|
||||
|
||||
final List<WifiNetworkEntity> _networks;
|
||||
@override@JsonKey() List<WifiNetworkEntity> get networks {
|
||||
if (_networks is EqualUnmodifiableListView) return _networks;
|
||||
final List<WifiNetworkEntity> _savedNetworks;
|
||||
@override@JsonKey() List<WifiNetworkEntity> get savedNetworks {
|
||||
if (_savedNetworks is EqualUnmodifiableListView) return _savedNetworks;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_networks);
|
||||
return EqualUnmodifiableListView(_savedNetworks);
|
||||
}
|
||||
|
||||
final List<ScannedWifiNetwork> _availableNetworks;
|
||||
@override@JsonKey() List<ScannedWifiNetwork> get availableNetworks {
|
||||
if (_availableNetworks is EqualUnmodifiableListView) return _availableNetworks;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_availableNetworks);
|
||||
}
|
||||
|
||||
@override final WifiNetworkEntity? currentNetwork;
|
||||
@override@JsonKey() final bool isLoading;
|
||||
@override@JsonKey() final bool isLoadingCurrentNetwork;
|
||||
@override@JsonKey() final bool isScanning;
|
||||
@override@JsonKey() final int scanSecondsRemaining;
|
||||
@override@JsonKey() final bool isSaving;
|
||||
@override@JsonKey() final String successMessage;
|
||||
@override@JsonKey() final String errorMessage;
|
||||
@override@JsonKey() final bool isConnecting;
|
||||
@override final WifiSettingsError? error;
|
||||
@override final WifiSettingsSuccess? success;
|
||||
|
||||
/// Create a copy of WifiSettingsViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@@ -235,16 +265,16 @@ _$WifiSettingsViewStateCopyWith<_WifiSettingsViewState> get copyWith => __$WifiS
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _WifiSettingsViewState&&const DeepCollectionEquality().equals(other._networks, _networks)&&(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 _WifiSettingsViewState&&const DeepCollectionEquality().equals(other._savedNetworks, _savedNetworks)&&const DeepCollectionEquality().equals(other._availableNetworks, _availableNetworks)&&(identical(other.currentNetwork, currentNetwork) || other.currentNetwork == currentNetwork)&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.isLoadingCurrentNetwork, isLoadingCurrentNetwork) || other.isLoadingCurrentNetwork == isLoadingCurrentNetwork)&&(identical(other.isScanning, isScanning) || other.isScanning == isScanning)&&(identical(other.scanSecondsRemaining, scanSecondsRemaining) || other.scanSecondsRemaining == scanSecondsRemaining)&&(identical(other.isSaving, isSaving) || other.isSaving == isSaving)&&(identical(other.isConnecting, isConnecting) || other.isConnecting == isConnecting)&&(identical(other.error, error) || other.error == error)&&(identical(other.success, success) || other.success == success));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_networks),isLoading,isSaving,successMessage,errorMessage);
|
||||
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_savedNetworks),const DeepCollectionEquality().hash(_availableNetworks),currentNetwork,isLoading,isLoadingCurrentNetwork,isScanning,scanSecondsRemaining,isSaving,isConnecting,error,success);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'WifiSettingsViewState(networks: $networks, isLoading: $isLoading, isSaving: $isSaving, successMessage: $successMessage, errorMessage: $errorMessage)';
|
||||
return 'WifiSettingsViewState(savedNetworks: $savedNetworks, availableNetworks: $availableNetworks, currentNetwork: $currentNetwork, isLoading: $isLoading, isLoadingCurrentNetwork: $isLoadingCurrentNetwork, isScanning: $isScanning, scanSecondsRemaining: $scanSecondsRemaining, isSaving: $isSaving, isConnecting: $isConnecting, error: $error, success: $success)';
|
||||
}
|
||||
|
||||
|
||||
@@ -255,11 +285,11 @@ abstract mixin class _$WifiSettingsViewStateCopyWith<$Res> implements $WifiSetti
|
||||
factory _$WifiSettingsViewStateCopyWith(_WifiSettingsViewState value, $Res Function(_WifiSettingsViewState) _then) = __$WifiSettingsViewStateCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
List<WifiNetworkEntity> networks, bool isLoading, bool isSaving, String successMessage, String errorMessage
|
||||
List<WifiNetworkEntity> savedNetworks, List<ScannedWifiNetwork> availableNetworks, WifiNetworkEntity? currentNetwork, bool isLoading, bool isLoadingCurrentNetwork, bool isScanning, int scanSecondsRemaining, bool isSaving, bool isConnecting, WifiSettingsError? error, WifiSettingsSuccess? success
|
||||
});
|
||||
|
||||
|
||||
|
||||
@override $WifiNetworkEntityCopyWith<$Res>? get currentNetwork;
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
@@ -272,18 +302,36 @@ class __$WifiSettingsViewStateCopyWithImpl<$Res>
|
||||
|
||||
/// Create a copy of WifiSettingsViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? networks = null,Object? isLoading = null,Object? isSaving = null,Object? successMessage = null,Object? errorMessage = null,}) {
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? savedNetworks = null,Object? availableNetworks = null,Object? currentNetwork = freezed,Object? isLoading = null,Object? isLoadingCurrentNetwork = null,Object? isScanning = null,Object? scanSecondsRemaining = null,Object? isSaving = null,Object? isConnecting = null,Object? error = freezed,Object? success = freezed,}) {
|
||||
return _then(_WifiSettingsViewState(
|
||||
networks: null == networks ? _self._networks : networks // ignore: cast_nullable_to_non_nullable
|
||||
as List<WifiNetworkEntity>,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,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,
|
||||
savedNetworks: null == savedNetworks ? _self._savedNetworks : savedNetworks // ignore: cast_nullable_to_non_nullable
|
||||
as List<WifiNetworkEntity>,availableNetworks: null == availableNetworks ? _self._availableNetworks : availableNetworks // ignore: cast_nullable_to_non_nullable
|
||||
as List<ScannedWifiNetwork>,currentNetwork: freezed == currentNetwork ? _self.currentNetwork : currentNetwork // ignore: cast_nullable_to_non_nullable
|
||||
as WifiNetworkEntity?,isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable
|
||||
as bool,isLoadingCurrentNetwork: null == isLoadingCurrentNetwork ? _self.isLoadingCurrentNetwork : isLoadingCurrentNetwork // ignore: cast_nullable_to_non_nullable
|
||||
as bool,isScanning: null == isScanning ? _self.isScanning : isScanning // ignore: cast_nullable_to_non_nullable
|
||||
as bool,scanSecondsRemaining: null == scanSecondsRemaining ? _self.scanSecondsRemaining : scanSecondsRemaining // ignore: cast_nullable_to_non_nullable
|
||||
as int,isSaving: null == isSaving ? _self.isSaving : isSaving // ignore: cast_nullable_to_non_nullable
|
||||
as bool,isConnecting: null == isConnecting ? _self.isConnecting : isConnecting // ignore: cast_nullable_to_non_nullable
|
||||
as bool,error: freezed == error ? _self.error : error // ignore: cast_nullable_to_non_nullable
|
||||
as WifiSettingsError?,success: freezed == success ? _self.success : success // ignore: cast_nullable_to_non_nullable
|
||||
as WifiSettingsSuccess?,
|
||||
));
|
||||
}
|
||||
|
||||
/// Create a copy of WifiSettingsViewState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$WifiNetworkEntityCopyWith<$Res>? get currentNetwork {
|
||||
if (_self.currentNetwork == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $WifiNetworkEntityCopyWith<$Res>(_self.currentNetwork!, (value) {
|
||||
return _then(_self.copyWith(currentNetwork: value));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// dart format on
|
||||
|
||||
@@ -6,45 +6,63 @@ import 'package:utils/utils.dart';
|
||||
|
||||
import '../state/wifi_settings_view_model.dart';
|
||||
|
||||
void showAddWifiNetworkSheet(BuildContext context) {
|
||||
void showConnectWifiSheet(
|
||||
BuildContext context, {
|
||||
String? ssid,
|
||||
String? bssid,
|
||||
}) {
|
||||
showModalBottomSheet<void>(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
backgroundColor: Colors.transparent,
|
||||
builder: (_) => const _AddWifiNetworkSheet(),
|
||||
builder: (_) => _ConnectWifiSheet(ssid: ssid, bssid: bssid),
|
||||
);
|
||||
}
|
||||
|
||||
class _AddWifiNetworkSheet extends ConsumerStatefulWidget {
|
||||
const _AddWifiNetworkSheet();
|
||||
class _ConnectWifiSheet extends ConsumerStatefulWidget {
|
||||
final String? ssid;
|
||||
final String? bssid;
|
||||
|
||||
const _ConnectWifiSheet({this.ssid, this.bssid});
|
||||
|
||||
@override
|
||||
ConsumerState<_AddWifiNetworkSheet> createState() =>
|
||||
_AddWifiNetworkSheetState();
|
||||
ConsumerState<_ConnectWifiSheet> createState() => _ConnectWifiSheetState();
|
||||
}
|
||||
|
||||
class _AddWifiNetworkSheetState extends ConsumerState<_AddWifiNetworkSheet> {
|
||||
final _ssidController = TextEditingController();
|
||||
final _bssidController = TextEditingController();
|
||||
class _ConnectWifiSheetState extends ConsumerState<_ConnectWifiSheet> {
|
||||
late final TextEditingController _ssidController;
|
||||
late final TextEditingController _bssidController;
|
||||
final _passwordController = TextEditingController();
|
||||
bool _obscurePassword = true;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_ssidController = TextEditingController(text: widget.ssid ?? '');
|
||||
_bssidController = TextEditingController(text: widget.bssid ?? '');
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_ssidController.dispose();
|
||||
_bssidController.dispose();
|
||||
_passwordController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
bool get _canSave =>
|
||||
_ssidController.text.trim().isNotEmpty &&
|
||||
_bssidController.text.trim().isNotEmpty;
|
||||
_bssidController.text.trim().isNotEmpty &&
|
||||
_passwordController.text.trim().isNotEmpty;
|
||||
|
||||
void _submit() {
|
||||
if (!_canSave) return;
|
||||
|
||||
final vm = ref.read(wifiSettingsViewModelProvider.notifier);
|
||||
vm.addNetwork(
|
||||
vm.connectAndSave(
|
||||
ssid: _ssidController.text.trim(),
|
||||
bssid: _bssidController.text.trim(),
|
||||
password: _passwordController.text.trim(),
|
||||
);
|
||||
Navigator.pop(context);
|
||||
}
|
||||
@@ -53,10 +71,11 @@ class _AddWifiNetworkSheetState extends ConsumerState<_AddWifiNetworkSheet> {
|
||||
Widget build(BuildContext context) {
|
||||
final theme = ref.watch(themePortProvider);
|
||||
final primaryColor = theme.getColorFor(ThemeCode.legacyPrimary);
|
||||
final isSaving = ref.watch(
|
||||
wifiSettingsViewModelProvider.select((s) => s.isSaving),
|
||||
final isConnecting = ref.watch(
|
||||
wifiSettingsViewModelProvider.select((s) => s.isConnecting),
|
||||
);
|
||||
final bottomInset = MediaQuery.of(context).viewInsets.bottom;
|
||||
final hasPrefilled = widget.ssid != null;
|
||||
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(bottom: bottomInset),
|
||||
@@ -91,7 +110,9 @@ class _AddWifiNetworkSheetState extends ConsumerState<_AddWifiNetworkSheet> {
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
context.translate(I18n.addWifiNetwork),
|
||||
hasPrefilled
|
||||
? context.translate(I18n.wifiConnectToNetwork)
|
||||
: context.translate(I18n.addWifiNetwork),
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 20, big: 21),
|
||||
fontWeight: FontWeight.w600,
|
||||
@@ -99,11 +120,12 @@ class _AddWifiNetworkSheetState extends ConsumerState<_AddWifiNetworkSheet> {
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: _canSave && !isSaving ? _submit : null,
|
||||
child: isSaving
|
||||
onPressed: _canSave && !isConnecting ? _submit : null,
|
||||
child: isConnecting
|
||||
? SizedBox(
|
||||
width: SizeUtils.getByScreen(small: 20, big: 22),
|
||||
height: SizeUtils.getByScreen(small: 20, big: 22),
|
||||
height:
|
||||
SizeUtils.getByScreen(small: 20, big: 22),
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
color: primaryColor,
|
||||
@@ -134,6 +156,7 @@ class _AddWifiNetworkSheetState extends ConsumerState<_AddWifiNetworkSheet> {
|
||||
SizedBox(height: 8),
|
||||
TextField(
|
||||
controller: _ssidController,
|
||||
readOnly: hasPrefilled,
|
||||
onChanged: (_) => setState(() {}),
|
||||
decoration: _inputDecoration(
|
||||
hintText: context.translate(I18n.wifiSsidHint),
|
||||
@@ -151,6 +174,7 @@ class _AddWifiNetworkSheetState extends ConsumerState<_AddWifiNetworkSheet> {
|
||||
SizedBox(height: 8),
|
||||
TextField(
|
||||
controller: _bssidController,
|
||||
readOnly: hasPrefilled,
|
||||
onChanged: (_) => setState(() {}),
|
||||
decoration: _inputDecoration(
|
||||
hintText: context.translate(I18n.wifiBssidHint),
|
||||
@@ -158,6 +182,36 @@ class _AddWifiNetworkSheetState extends ConsumerState<_AddWifiNetworkSheet> {
|
||||
),
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 18)),
|
||||
Text(
|
||||
context.translate(I18n.wifiPassword),
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 15, big: 16),
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
TextField(
|
||||
controller: _passwordController,
|
||||
obscureText: _obscurePassword,
|
||||
onChanged: (_) => setState(() {}),
|
||||
decoration: _inputDecoration(
|
||||
hintText: context.translate(I18n.wifiPasswordHint),
|
||||
primaryColor: primaryColor,
|
||||
).copyWith(
|
||||
suffixIcon: IconButton(
|
||||
onPressed: () =>
|
||||
setState(() => _obscurePassword = !_obscurePassword),
|
||||
icon: Icon(
|
||||
_obscurePassword
|
||||
? Icons.visibility_off
|
||||
: Icons.visibility,
|
||||
color: Colors.grey,
|
||||
size: SizeUtils.getByScreen(small: 22, big: 24),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 18)),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
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/entities/scanned_wifi_network.dart';
|
||||
|
||||
class AvailableWifiNetworkCard extends ConsumerWidget {
|
||||
final ScannedWifiNetwork network;
|
||||
final VoidCallback onTap;
|
||||
|
||||
const AvailableWifiNetworkCard({
|
||||
super.key,
|
||||
required this.network,
|
||||
required this.onTap,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final theme = ref.watch(themePortProvider);
|
||||
final primaryColor = theme.getColorFor(ThemeCode.legacyPrimary);
|
||||
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(
|
||||
bottom: SizeUtils.getByScreen(small: 10, big: 8),
|
||||
),
|
||||
child: GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: SizeUtils.getByScreen(small: 16, big: 14),
|
||||
vertical: SizeUtils.getByScreen(small: 14, big: 12),
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: theme.getColorFor(ThemeCode.backgroundSecondary),
|
||||
borderRadius: BorderRadius.all(Radius.circular(16)),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.wifi,
|
||||
color: primaryColor,
|
||||
size: SizeUtils.getByScreen(small: 28, big: 30),
|
||||
),
|
||||
SizedBox(width: SizeUtils.getByScreen(small: 12, big: 14)),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
network.ssid,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: theme.getColorFor(ThemeCode.textPrimary),
|
||||
fontSize: SizeUtils.getByScreen(small: 15, big: 16),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 2),
|
||||
Text(
|
||||
network.bssid,
|
||||
style: TextStyle(
|
||||
color: theme
|
||||
.getColorFor(ThemeCode.textPrimary)
|
||||
.withAlpha(178),
|
||||
fontSize: SizeUtils.getByScreen(small: 13, big: 14),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Icon(
|
||||
Icons.chevron_right,
|
||||
color: theme
|
||||
.getColorFor(ThemeCode.textPrimary)
|
||||
.withAlpha(178),
|
||||
size: SizeUtils.getByScreen(small: 24, big: 26),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,8 @@ import 'package:sf_localizations/sf_localizations.dart';
|
||||
import 'package:utils/utils.dart';
|
||||
|
||||
import 'state/wifi_settings_view_model.dart';
|
||||
import 'state/wifi_settings_view_state.dart';
|
||||
import 'widgets/available_wifi_network_card.dart';
|
||||
import 'widgets/add_wifi_network_sheet.dart';
|
||||
import 'widgets/wifi_network_card.dart';
|
||||
|
||||
@@ -19,33 +21,41 @@ class WifiSettingsScreen extends ConsumerWidget {
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final theme = ref.watch(themePortProvider);
|
||||
final state = ref.watch(wifiSettingsViewModelProvider);
|
||||
final vm = ref.read(wifiSettingsViewModelProvider.notifier);
|
||||
final primaryColor = theme.getColorFor(ThemeCode.legacyPrimary);
|
||||
|
||||
ref.listen(wifiSettingsViewModelProvider.select((s) => s.errorMessage), (
|
||||
ref.listen(wifiSettingsViewModelProvider.select((s) => s.error), (
|
||||
_,
|
||||
errorMessage,
|
||||
error,
|
||||
) {
|
||||
if (errorMessage.isNotEmpty) {
|
||||
showTopSnackbar(
|
||||
context,
|
||||
message: errorMessage,
|
||||
type: MessageType.error,
|
||||
);
|
||||
}
|
||||
if (error == null) return;
|
||||
final message = switch (error) {
|
||||
WifiSettingsError.loadFailed => context.translate(I18n.wifiLoadError),
|
||||
WifiSettingsError.scanFailed => context.translate(I18n.wifiScanFailed),
|
||||
WifiSettingsError.connectFailed =>
|
||||
context.translate(I18n.wifiConnectFailed),
|
||||
WifiSettingsError.saveFailed => context.translate(I18n.wifiSaveFailed),
|
||||
WifiSettingsError.deleteFailed =>
|
||||
context.translate(I18n.wifiDeleteFailed),
|
||||
};
|
||||
showTopSnackbar(context, message: message, type: MessageType.error);
|
||||
vm.clearError();
|
||||
});
|
||||
|
||||
ref.listen(wifiSettingsViewModelProvider.select((s) => s.successMessage), (
|
||||
ref.listen(wifiSettingsViewModelProvider.select((s) => s.success), (
|
||||
_,
|
||||
successMessage,
|
||||
success,
|
||||
) {
|
||||
if (successMessage.isNotEmpty) {
|
||||
showTopSnackbar(
|
||||
context,
|
||||
message: context.translate(successMessage),
|
||||
type: MessageType.success,
|
||||
);
|
||||
ref.read(wifiSettingsViewModelProvider.notifier).clearSuccess();
|
||||
}
|
||||
if (success == null) return;
|
||||
final message = switch (success) {
|
||||
WifiSettingsSuccess.networkSaved =>
|
||||
context.translate(I18n.wifiNetworkSaved),
|
||||
WifiSettingsSuccess.networkDeleted =>
|
||||
context.translate(I18n.wifiNetworkDeleted),
|
||||
WifiSettingsSuccess.connected => context.translate(I18n.wifiConnected),
|
||||
};
|
||||
showTopSnackbar(context, message: message, type: MessageType.success);
|
||||
vm.clearSuccess();
|
||||
});
|
||||
|
||||
return Scaffold(
|
||||
@@ -65,7 +75,7 @@ class WifiSettingsScreen extends ConsumerWidget {
|
||||
),
|
||||
),
|
||||
title: Text(
|
||||
context.translate(I18n.wifiSettings).toUpperCase(),
|
||||
'WiFi',
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 20, big: 19),
|
||||
fontWeight: FontWeight.w500,
|
||||
@@ -86,10 +96,10 @@ class WifiSettingsScreen extends ConsumerWidget {
|
||||
child: IconButton(
|
||||
onPressed: () {
|
||||
if (!guardDeviceCommand(context, ref)) return;
|
||||
showAddWifiNetworkSheet(context);
|
||||
vm.scanNetworks();
|
||||
},
|
||||
icon: Icon(
|
||||
Icons.add,
|
||||
Icons.wifi_find,
|
||||
color: Colors.white,
|
||||
size: SizeUtils.getByScreen(small: 24, big: 22),
|
||||
),
|
||||
@@ -102,68 +112,19 @@ class WifiSettingsScreen extends ConsumerWidget {
|
||||
top: false,
|
||||
child: state.isLoading
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: state.networks.isEmpty
|
||||
? _EmptyState(primaryColor: primaryColor)
|
||||
: _NetworkList(),
|
||||
: _Body(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
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.wifi_off_outlined,
|
||||
color: primaryColor,
|
||||
size: SizeUtils.getByScreen(small: 120, big: 140),
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 20, big: 24)),
|
||||
Text(
|
||||
context.translate(I18n.noWifiNetworks),
|
||||
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.noWifiNetworksDescription),
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 14, big: 15),
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _NetworkList extends ConsumerWidget {
|
||||
const _NetworkList();
|
||||
class _Body extends ConsumerWidget {
|
||||
const _Body();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final theme = ref.watch(themePortProvider);
|
||||
final networks = ref.watch(
|
||||
wifiSettingsViewModelProvider.select((s) => s.networks),
|
||||
);
|
||||
final state = ref.watch(wifiSettingsViewModelProvider);
|
||||
final primaryColor = theme.getColorFor(ThemeCode.legacyPrimary);
|
||||
|
||||
return SingleChildScrollView(
|
||||
@@ -175,46 +136,145 @@ class _NetworkList extends ConsumerWidget {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.only(
|
||||
bottom: SizeUtils.getByScreen(small: 12, big: 10),
|
||||
),
|
||||
child: Text(
|
||||
context.translate(I18n.wifiDescription),
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 14, big: 15),
|
||||
color: theme
|
||||
.getColorFor(ThemeCode.textPrimary)
|
||||
.withAlpha(178),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
_sectionTitle(
|
||||
context,
|
||||
context.translate(I18n.wifiCurrentNetwork),
|
||||
primaryColor,
|
||||
),
|
||||
if (state.isLoadingCurrentNetwork)
|
||||
SizedBox(
|
||||
width: SizeUtils.getByScreen(small: 16, big: 14),
|
||||
height: SizeUtils.getByScreen(small: 16, big: 14),
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
color: primaryColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 8, big: 6)),
|
||||
if (state.currentNetwork != null)
|
||||
_CurrentNetworkCard(
|
||||
ssid: state.currentNetwork!.ssid,
|
||||
bssid: state.currentNetwork!.bssid,
|
||||
theme: theme,
|
||||
)
|
||||
else if (!state.isLoadingCurrentNetwork)
|
||||
Padding(
|
||||
padding: EdgeInsets.only(
|
||||
bottom: SizeUtils.getByScreen(small: 12, big: 10),
|
||||
),
|
||||
child: Text(
|
||||
context.translate(I18n.wifiNoCurrentNetwork),
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 14, big: 15),
|
||||
color: theme
|
||||
.getColorFor(ThemeCode.textPrimary)
|
||||
.withAlpha(178),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
...List.generate(networks.length, (index) {
|
||||
final network = networks[index];
|
||||
return WifiNetworkCard(
|
||||
network: network,
|
||||
onDelete: () => _confirmDelete(context, ref, network),
|
||||
theme: theme,
|
||||
);
|
||||
}),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 12, big: 10)),
|
||||
Text(
|
||||
if (state.availableNetworks.isNotEmpty || state.isScanning) ...[
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 14)),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
_sectionTitle(
|
||||
context,
|
||||
context.translate(I18n.wifiAvailableNetworks),
|
||||
primaryColor,
|
||||
),
|
||||
if (state.isScanning)
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
'${state.scanSecondsRemaining}s',
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 13, big: 12),
|
||||
fontWeight: FontWeight.w600,
|
||||
color: primaryColor,
|
||||
),
|
||||
),
|
||||
SizedBox(width: SizeUtils.getByScreen(small: 6, big: 5)),
|
||||
SizedBox(
|
||||
width: SizeUtils.getByScreen(small: 16, big: 14),
|
||||
height: SizeUtils.getByScreen(small: 16, big: 14),
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
color: primaryColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 8, big: 6)),
|
||||
...state.availableNetworks.map(
|
||||
(network) => AvailableWifiNetworkCard(
|
||||
network: network,
|
||||
onTap: () => showConnectWifiSheet(
|
||||
context,
|
||||
ssid: network.ssid,
|
||||
bssid: network.bssid,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 16, big: 14)),
|
||||
_sectionTitle(
|
||||
context,
|
||||
context.translate(
|
||||
I18n.wifiNetworksCount,
|
||||
args: {'count': networks.length.toString()},
|
||||
),
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 13, big: 14),
|
||||
color: primaryColor,
|
||||
fontWeight: FontWeight.w500,
|
||||
I18n.wifiSavedNetworks,
|
||||
args: {'count': state.savedNetworks.length.toString()},
|
||||
),
|
||||
primaryColor,
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 8, big: 6)),
|
||||
if (state.savedNetworks.isEmpty)
|
||||
Padding(
|
||||
padding: EdgeInsets.only(
|
||||
bottom: SizeUtils.getByScreen(small: 12, big: 10),
|
||||
),
|
||||
child: Text(
|
||||
context.translate(I18n.noWifiNetworks),
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 14, big: 15),
|
||||
color: theme
|
||||
.getColorFor(ThemeCode.textPrimary)
|
||||
.withAlpha(178),
|
||||
),
|
||||
),
|
||||
)
|
||||
else
|
||||
...state.savedNetworks.map(
|
||||
(network) => WifiNetworkCard(
|
||||
network: network,
|
||||
onDelete: () => _confirmDelete(context, ref, network),
|
||||
theme: theme,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _sectionTitle(BuildContext context, String text, Color color) {
|
||||
return Text(
|
||||
text.toUpperCase(),
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 13, big: 14),
|
||||
fontWeight: FontWeight.w600,
|
||||
letterSpacing: 0.5,
|
||||
color: color,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _confirmDelete(BuildContext context, WidgetRef ref, dynamic network) {
|
||||
if (!guardDeviceCommand(context, ref)) return;
|
||||
final theme = ref.read(themePortProvider);
|
||||
@@ -255,3 +315,69 @@ class _NetworkList extends ConsumerWidget {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _CurrentNetworkCard extends StatelessWidget {
|
||||
final String ssid;
|
||||
final String bssid;
|
||||
final ThemePort theme;
|
||||
|
||||
const _CurrentNetworkCard({
|
||||
required this.ssid,
|
||||
required this.bssid,
|
||||
required this.theme,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(
|
||||
bottom: SizeUtils.getByScreen(small: 10, big: 8),
|
||||
),
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: SizeUtils.getByScreen(small: 16, big: 14),
|
||||
vertical: SizeUtils.getByScreen(small: 14, big: 12),
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: theme.getColorFor(ThemeCode.backgroundSecondary),
|
||||
borderRadius: BorderRadius.all(Radius.circular(16)),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.wifi,
|
||||
color: theme.getColorFor(ThemeCode.legacyPrimary),
|
||||
size: SizeUtils.getByScreen(small: 28, big: 30),
|
||||
),
|
||||
SizedBox(width: SizeUtils.getByScreen(small: 12, big: 14)),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
ssid,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: theme.getColorFor(ThemeCode.textPrimary),
|
||||
fontSize: SizeUtils.getByScreen(small: 15, big: 16),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 2),
|
||||
Text(
|
||||
bssid,
|
||||
style: TextStyle(
|
||||
color: theme
|
||||
.getColorFor(ThemeCode.textPrimary)
|
||||
.withAlpha(178),
|
||||
fontSize: SizeUtils.getByScreen(small: 13, big: 14),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,14 @@ enum DeviceCommand {
|
||||
setBackgroundImage,
|
||||
@JsonValue('SET_SOUND_MODE')
|
||||
setSoundMode,
|
||||
@JsonValue('WIFI_CURRENT')
|
||||
wifiCurrent,
|
||||
@JsonValue('WIFI_SEARCH')
|
||||
wifiSearch,
|
||||
@JsonValue('SET_WIFI')
|
||||
setWifi,
|
||||
@JsonValue('WIFI_DELETE')
|
||||
wifiDelete,
|
||||
}
|
||||
|
||||
@freezed
|
||||
|
||||
@@ -33,4 +33,8 @@ const _$DeviceCommandEnumMap = {
|
||||
DeviceCommand.shutdown: 'SHUTDOWN',
|
||||
DeviceCommand.setBackgroundImage: 'SET_BACKGROUND_IMG',
|
||||
DeviceCommand.setSoundMode: 'SET_SOUND_MODE',
|
||||
DeviceCommand.wifiCurrent: 'WIFI_CURRENT',
|
||||
DeviceCommand.wifiSearch: 'WIFI_SEARCH',
|
||||
DeviceCommand.setWifi: 'SET_WIFI',
|
||||
DeviceCommand.wifiDelete: 'WIFI_DELETE',
|
||||
};
|
||||
|
||||
@@ -576,6 +576,22 @@
|
||||
"wifiBssid": "MAC-Adresse (BSSID)",
|
||||
"wifiSsidHint": "z.B. MeinHeimWLAN",
|
||||
"wifiBssidHint": "z.B. 0c:80:63:e4:cb:e1",
|
||||
"wifiCurrentNetwork": "Aktuelles Netzwerk",
|
||||
"wifiAvailableNetworks": "Verfügbare Netzwerke",
|
||||
"wifiSavedNetworks": "{count} gespeicherte Netzwerke",
|
||||
"wifiScan": "Scannen",
|
||||
"wifiNoCurrentNetwork": "Kein Netzwerk verbunden",
|
||||
"wifiLoadError": "Fehler beim Laden der WLAN-Netzwerke",
|
||||
"wifiScanFailed": "Netzwerksuche fehlgeschlagen",
|
||||
"wifiConnectFailed": "Verbindung fehlgeschlagen",
|
||||
"wifiSaveFailed": "Netzwerk speichern fehlgeschlagen",
|
||||
"wifiDeleteFailed": "Netzwerk löschen fehlgeschlagen",
|
||||
"wifiNetworkSaved": "Netzwerk erfolgreich gespeichert",
|
||||
"wifiNetworkDeleted": "Netzwerk erfolgreich gelöscht",
|
||||
"wifiConnected": "Erfolgreich verbunden",
|
||||
"wifiPassword": "Passwort",
|
||||
"wifiPasswordHint": "Netzwerk-Passwort eingeben",
|
||||
"wifiConnectToNetwork": "Mit Netzwerk verbinden",
|
||||
"editChildProfile": "Profil bearbeiten",
|
||||
"editChildProfileTitle": "Kinderprofil bearbeiten",
|
||||
"editChildProfileSaveSuccess": "Kinderprofil erfolgreich aktualisiert",
|
||||
|
||||
@@ -733,6 +733,22 @@
|
||||
"wifiBssid": "MAC address (BSSID)",
|
||||
"wifiSsidHint": "e.g. MyHomeWiFi",
|
||||
"wifiBssidHint": "e.g. 0c:80:63:e4:cb:e1",
|
||||
"wifiCurrentNetwork": "Current network",
|
||||
"wifiAvailableNetworks": "Available networks",
|
||||
"wifiSavedNetworks": "{count} saved networks",
|
||||
"wifiScan": "Scan",
|
||||
"wifiNoCurrentNetwork": "No network connected",
|
||||
"wifiLoadError": "Error loading WiFi networks",
|
||||
"wifiScanFailed": "Failed to scan networks",
|
||||
"wifiConnectFailed": "Failed to connect",
|
||||
"wifiSaveFailed": "Failed to save network",
|
||||
"wifiDeleteFailed": "Failed to delete network",
|
||||
"wifiNetworkSaved": "Network saved successfully",
|
||||
"wifiNetworkDeleted": "Network deleted successfully",
|
||||
"wifiConnected": "Connected successfully",
|
||||
"wifiPassword": "Password",
|
||||
"wifiPasswordHint": "Enter the network password",
|
||||
"wifiConnectToNetwork": "Connect to network",
|
||||
"editChildProfile": "Edit profile",
|
||||
"editChildProfileSaveSuccess": "Child profile updated successfully",
|
||||
"editChildProfileTitle": "Edit child profile",
|
||||
|
||||
@@ -734,6 +734,22 @@
|
||||
"wifiBssid": "Dirección MAC (BSSID)",
|
||||
"wifiSsidHint": "ej. MiWiFiCasa",
|
||||
"wifiBssidHint": "ej. 0c:80:63:e4:cb:e1",
|
||||
"wifiCurrentNetwork": "Red actual",
|
||||
"wifiAvailableNetworks": "Redes disponibles",
|
||||
"wifiSavedNetworks": "{count} redes guardadas",
|
||||
"wifiScan": "Escanear",
|
||||
"wifiNoCurrentNetwork": "Sin red conectada",
|
||||
"wifiLoadError": "Error al cargar redes WiFi",
|
||||
"wifiScanFailed": "Error al escanear redes",
|
||||
"wifiConnectFailed": "Error al conectar",
|
||||
"wifiSaveFailed": "Error al guardar red",
|
||||
"wifiDeleteFailed": "Error al eliminar red",
|
||||
"wifiNetworkSaved": "Red guardada correctamente",
|
||||
"wifiNetworkDeleted": "Red eliminada correctamente",
|
||||
"wifiConnected": "Conectado correctamente",
|
||||
"wifiPassword": "Contraseña",
|
||||
"wifiPasswordHint": "Ingresa la contraseña de la red",
|
||||
"wifiConnectToNetwork": "Conectar a red",
|
||||
"editChildProfile": "Editar perfil",
|
||||
"editChildProfileTitle": "Editar perfil del niño",
|
||||
"editChildProfileSaveSuccess": "Perfil del niño actualizado correctamente",
|
||||
|
||||
@@ -576,6 +576,22 @@
|
||||
"wifiBssid": "Adresse MAC (BSSID)",
|
||||
"wifiSsidHint": "ex. MonWiFiMaison",
|
||||
"wifiBssidHint": "ex. 0c:80:63:e4:cb:e1",
|
||||
"wifiCurrentNetwork": "Réseau actuel",
|
||||
"wifiAvailableNetworks": "Réseaux disponibles",
|
||||
"wifiSavedNetworks": "{count} réseaux enregistrés",
|
||||
"wifiScan": "Scanner",
|
||||
"wifiNoCurrentNetwork": "Aucun réseau connecté",
|
||||
"wifiLoadError": "Erreur lors du chargement des réseaux WiFi",
|
||||
"wifiScanFailed": "Échec de la recherche de réseaux",
|
||||
"wifiConnectFailed": "Échec de la connexion",
|
||||
"wifiSaveFailed": "Échec de l'enregistrement du réseau",
|
||||
"wifiDeleteFailed": "Échec de la suppression du réseau",
|
||||
"wifiNetworkSaved": "Réseau enregistré avec succès",
|
||||
"wifiNetworkDeleted": "Réseau supprimé avec succès",
|
||||
"wifiConnected": "Connecté avec succès",
|
||||
"wifiPassword": "Mot de passe",
|
||||
"wifiPasswordHint": "Entrez le mot de passe du réseau",
|
||||
"wifiConnectToNetwork": "Se connecter au réseau",
|
||||
"editChildProfile": "Modifier le profil",
|
||||
"editChildProfileTitle": "Modifier le profil de l'enfant",
|
||||
"editChildProfileSaveSuccess": "Profil de l'enfant mis à jour avec succès",
|
||||
|
||||
@@ -576,6 +576,22 @@
|
||||
"wifiBssid": "Indirizzo MAC (BSSID)",
|
||||
"wifiSsidHint": "es. MiaReteCasa",
|
||||
"wifiBssidHint": "es. 0c:80:63:e4:cb:e1",
|
||||
"wifiCurrentNetwork": "Rete attuale",
|
||||
"wifiAvailableNetworks": "Reti disponibili",
|
||||
"wifiSavedNetworks": "{count} reti salvate",
|
||||
"wifiScan": "Scansiona",
|
||||
"wifiNoCurrentNetwork": "Nessuna rete connessa",
|
||||
"wifiLoadError": "Errore nel caricamento delle reti WiFi",
|
||||
"wifiScanFailed": "Scansione reti fallita",
|
||||
"wifiConnectFailed": "Connessione fallita",
|
||||
"wifiSaveFailed": "Salvataggio rete fallito",
|
||||
"wifiDeleteFailed": "Eliminazione rete fallita",
|
||||
"wifiNetworkSaved": "Rete salvata con successo",
|
||||
"wifiNetworkDeleted": "Rete eliminata con successo",
|
||||
"wifiConnected": "Connesso con successo",
|
||||
"wifiPassword": "Password",
|
||||
"wifiPasswordHint": "Inserisci la password della rete",
|
||||
"wifiConnectToNetwork": "Connetti alla rete",
|
||||
"editChildProfile": "Modifica profilo",
|
||||
"editChildProfileTitle": "Modifica profilo del bambino",
|
||||
"editChildProfileSaveSuccess": "Profilo del bambino aggiornato con successo",
|
||||
|
||||
@@ -576,6 +576,22 @@
|
||||
"wifiBssid": "Endereço MAC (BSSID)",
|
||||
"wifiSsidHint": "ex. MinhaRedeWiFi",
|
||||
"wifiBssidHint": "ex. 0c:80:63:e4:cb:e1",
|
||||
"wifiCurrentNetwork": "Rede atual",
|
||||
"wifiAvailableNetworks": "Redes disponíveis",
|
||||
"wifiSavedNetworks": "{count} redes guardadas",
|
||||
"wifiScan": "Procurar",
|
||||
"wifiNoCurrentNetwork": "Nenhuma rede conectada",
|
||||
"wifiLoadError": "Erro ao carregar redes WiFi",
|
||||
"wifiScanFailed": "Falha ao procurar redes",
|
||||
"wifiConnectFailed": "Falha ao conectar",
|
||||
"wifiSaveFailed": "Falha ao guardar rede",
|
||||
"wifiDeleteFailed": "Falha ao eliminar rede",
|
||||
"wifiNetworkSaved": "Rede guardada com sucesso",
|
||||
"wifiNetworkDeleted": "Rede eliminada com sucesso",
|
||||
"wifiConnected": "Conectado com sucesso",
|
||||
"wifiPassword": "Palavra-passe",
|
||||
"wifiPasswordHint": "Introduza a palavra-passe da rede",
|
||||
"wifiConnectToNetwork": "Conectar à rede",
|
||||
"editChildProfile": "Editar perfil",
|
||||
"editChildProfileTitle": "Editar perfil da criança",
|
||||
"editChildProfileSaveSuccess": "Perfil da criança atualizado com sucesso",
|
||||
|
||||
@@ -986,12 +986,28 @@ class I18n {
|
||||
static const String wednesday = 'wednesday';
|
||||
static const String welcome = 'welcome';
|
||||
static const String whitelistDescription = 'whitelistDescription';
|
||||
static const String wifiAvailableNetworks = 'wifiAvailableNetworks';
|
||||
static const String wifiBssid = 'wifiBssid';
|
||||
static const String wifiBssidHint = 'wifiBssidHint';
|
||||
static const String wifiConnectFailed = 'wifiConnectFailed';
|
||||
static const String wifiConnectToNetwork = 'wifiConnectToNetwork';
|
||||
static const String wifiConnected = 'wifiConnected';
|
||||
static const String wifiCurrentNetwork = 'wifiCurrentNetwork';
|
||||
static const String wifiDeleteFailed = 'wifiDeleteFailed';
|
||||
static const String wifiDescription = 'wifiDescription';
|
||||
static const String wifiLoadError = 'wifiLoadError';
|
||||
static const String wifiNetworkAdded = 'wifiNetworkAdded';
|
||||
static const String wifiNetworkDeleted = 'wifiNetworkDeleted';
|
||||
static const String wifiNetworkRemoved = 'wifiNetworkRemoved';
|
||||
static const String wifiNetworkSaved = 'wifiNetworkSaved';
|
||||
static const String wifiNetworksCount = 'wifiNetworksCount';
|
||||
static const String wifiNoCurrentNetwork = 'wifiNoCurrentNetwork';
|
||||
static const String wifiPassword = 'wifiPassword';
|
||||
static const String wifiPasswordHint = 'wifiPasswordHint';
|
||||
static const String wifiSaveFailed = 'wifiSaveFailed';
|
||||
static const String wifiSavedNetworks = 'wifiSavedNetworks';
|
||||
static const String wifiScan = 'wifiScan';
|
||||
static const String wifiScanFailed = 'wifiScanFailed';
|
||||
static const String wifiSettings = 'wifiSettings';
|
||||
static const String wifiSsid = 'wifiSsid';
|
||||
static const String wifiSsidHint = 'wifiSsidHint';
|
||||
|
||||
Reference in New Issue
Block a user