Compare commits

...

1 Commits

Author SHA1 Message Date
62827fce1e fix sound mode command 2026-03-20 12:05:48 +01:00
10 changed files with 71 additions and 71 deletions

View File

@@ -26,7 +26,7 @@ late final GoRouter appRouter;
void configureAppRouter() {
appRouter = GoRouter(
navigatorKey: rootNavigatorKey,
initialLocation: AppRoutes.splash,
initialLocation: AppRoutes.controlPanel,
debugLogDiagnostics: true,
routes: [
GoRoute(

View File

@@ -1,3 +0,0 @@
abstract class SetSoundUseCase {
Future<void> setSound({required String deviceId});
}

View File

@@ -1,16 +0,0 @@
import 'package:settings/src/core/domain/repositories/settings_repository.dart';
import 'set_sound_use_case.dart';
class SetSoundUseCaseImpl implements SetSoundUseCase {
SetSoundUseCaseImpl(this._repository);
final SettingsRepository _repository;
@override
Future<void> setSound({required String deviceId}) async {
return;
// return _repository.setSound(deviceId: deviceId);
}
}

View File

@@ -1,10 +0,0 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:settings/src/core/providers/settings_repository_provider.dart';
import '../../domain/set_sound_use_case.dart';
import '../../domain/set_sound_use_case_impl.dart';
final setSoundUseCaseProvider = Provider.autoDispose<SetSoundUseCase>((ref) {
final settingsRepository = ref.read(settingsRepositoryProvider);
return SetSoundUseCaseImpl(settingsRepository);
});

View File

@@ -20,6 +20,26 @@ class SoundScreen extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
final theme = ref.read(themePortProvider);
ref.listen(soundViewModelProvider.select((s) => s.errorMessage), (
_,
errorMessage,
) {
if (errorMessage.isNotEmpty) {
showTopSnackbar(
context,
message: errorMessage,
type: MessageType.error,
);
}
});
ref.listen(soundViewModelProvider.select((s) => s.isComplete), (
_,
isComplete,
) {
if (isComplete) Navigator.pop(context);
});
return LegacyPageLayout(
theme: theme,
title: context.translate(I18n.sound),
@@ -61,15 +81,15 @@ class _OptionsSection extends ConsumerWidget {
_SectionButton(
title: context.translate(I18n.soundAndVibration),
icon: Icons.volume_up_outlined,
active: soundOption == 'SOUND_AND_VIBRATION',
onPressed: () {vm.setSoundOption('SOUND_AND_VIBRATION');},
active: soundOption == 'VIBRATION_AND_RINGING',
onPressed: () {vm.setSoundOption('VIBRATION_AND_RINGING');},
),
SizedBox(height: 12),
_SectionButton(
title: context.translate(I18n.soundOnly),
icon: Icons.volume_up_outlined,
active: soundOption == 'SOUND',
onPressed: () {vm.setSoundOption('SOUND');},
active: soundOption == 'RINGING',
onPressed: () {vm.setSoundOption('RINGING');},
),
SizedBox(height: 12),
_SectionButton(
@@ -82,8 +102,8 @@ class _OptionsSection extends ConsumerWidget {
_SectionButton(
title: context.translate(I18n.silent),
icon: Icons.volume_mute_outlined,
active: soundOption == 'SILENT',
onPressed: () {vm.setSoundOption('SILENT');},
active: soundOption == 'SILENCE',
onPressed: () {vm.setSoundOption('SILENCE');},
),
]
),
@@ -152,7 +172,7 @@ class _SaveSection extends ConsumerWidget {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 24, vertical: 12),
child: PrimaryButton(
onPressed: vm.submit,
onPressed: () {vm.submit();},
text: context.translate(I18n.save),
color: theme.getColorFor(ThemeCode.legacyPrimary)
),

View File

@@ -1,9 +1,6 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:legacy_shared/legacy_shared.dart';
import 'package:sf_shared/sf_shared.dart';
import '../../domain/set_sound_use_case.dart';
import '../providers/set_sound_use_case_provider.dart';
import 'sound_view_state.dart';
final soundViewModelProvider =
@@ -12,11 +9,11 @@ NotifierProvider.autoDispose<SoundViewModel, SoundViewState>(
);
class SoundViewModel extends Notifier<SoundViewState> {
late final SetSoundUseCase _setSoundUseCase;
late final CommandsRepository _commandsRepository;
@override
SoundViewState build() {
_setSoundUseCase = ref.read(setSoundUseCaseProvider);
_commandsRepository = ref.read(commandsRepositoryProvider);
Future.microtask(() => load());
@@ -25,16 +22,12 @@ class SoundViewModel extends Notifier<SoundViewState> {
Future<void> load() async {
final device = ref.read(selectedDeviceProvider);
setDevice(device!);
state = state.copyWith(
soundOption: 'SOUND_AND_VIBRATION',
isLoading: false,
);
}
if (device == null) return;
void setDevice(DeviceEntity device) {
state = state.copyWith(
deviceId: device.identificator,
soundOption: device.settings['soundMode'] ?? 'VIBRATION',
isLoading: false,
);
}
@@ -50,8 +43,20 @@ class SoundViewModel extends Notifier<SoundViewState> {
try {
state = state.copyWith(
isLoading: true,
isComplete: false,
);
final request = SendCommandRequestModel(
device: state.deviceId,
command: DeviceCommand.setSoundMode,
data: {'soundMode': state.soundOption}
);
await _commandsRepository.send(request: request);
state = state.copyWith(
isLoading: false,
isComplete: true,
);
_setSoundUseCase.setSound(deviceId: state.deviceId);
} catch (e) {
state = state.copyWith(
isLoading: false,

View File

@@ -9,6 +9,7 @@ abstract class SoundViewState with _$SoundViewState {
@Default('') String deviceId,
String? soundOption,
@Default(true) bool isLoading,
@Default(false) bool isComplete,
@Default('') String errorMessage,
}) = _SoundViewState;
}

View File

@@ -14,7 +14,7 @@ T _$identity<T>(T value) => value;
/// @nodoc
mixin _$SoundViewState {
String get deviceId; String? get soundOption; bool get isLoading; String get errorMessage;
String get deviceId; String? get soundOption; bool get isLoading; bool get isComplete; String get errorMessage;
/// Create a copy of SoundViewState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -25,16 +25,16 @@ $SoundViewStateCopyWith<SoundViewState> get copyWith => _$SoundViewStateCopyWith
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is SoundViewState&&(identical(other.deviceId, deviceId) || other.deviceId == deviceId)&&(identical(other.soundOption, soundOption) || other.soundOption == soundOption)&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage));
return identical(this, other) || (other.runtimeType == runtimeType&&other is SoundViewState&&(identical(other.deviceId, deviceId) || other.deviceId == deviceId)&&(identical(other.soundOption, soundOption) || other.soundOption == soundOption)&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.isComplete, isComplete) || other.isComplete == isComplete)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage));
}
@override
int get hashCode => Object.hash(runtimeType,deviceId,soundOption,isLoading,errorMessage);
int get hashCode => Object.hash(runtimeType,deviceId,soundOption,isLoading,isComplete,errorMessage);
@override
String toString() {
return 'SoundViewState(deviceId: $deviceId, soundOption: $soundOption, isLoading: $isLoading, errorMessage: $errorMessage)';
return 'SoundViewState(deviceId: $deviceId, soundOption: $soundOption, isLoading: $isLoading, isComplete: $isComplete, errorMessage: $errorMessage)';
}
@@ -45,7 +45,7 @@ abstract mixin class $SoundViewStateCopyWith<$Res> {
factory $SoundViewStateCopyWith(SoundViewState value, $Res Function(SoundViewState) _then) = _$SoundViewStateCopyWithImpl;
@useResult
$Res call({
String deviceId, String? soundOption, bool isLoading, String errorMessage
String deviceId, String? soundOption, bool isLoading, bool isComplete, String errorMessage
});
@@ -62,11 +62,12 @@ class _$SoundViewStateCopyWithImpl<$Res>
/// Create a copy of SoundViewState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? deviceId = null,Object? soundOption = freezed,Object? isLoading = null,Object? errorMessage = null,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? deviceId = null,Object? soundOption = freezed,Object? isLoading = null,Object? isComplete = null,Object? errorMessage = null,}) {
return _then(_self.copyWith(
deviceId: null == deviceId ? _self.deviceId : deviceId // ignore: cast_nullable_to_non_nullable
as String,soundOption: freezed == soundOption ? _self.soundOption : soundOption // ignore: cast_nullable_to_non_nullable
as String?,isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable
as bool,isComplete: null == isComplete ? _self.isComplete : isComplete // ignore: cast_nullable_to_non_nullable
as bool,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
as String,
));
@@ -153,10 +154,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String deviceId, String? soundOption, bool isLoading, String errorMessage)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String deviceId, String? soundOption, bool isLoading, bool isComplete, String errorMessage)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _SoundViewState() when $default != null:
return $default(_that.deviceId,_that.soundOption,_that.isLoading,_that.errorMessage);case _:
return $default(_that.deviceId,_that.soundOption,_that.isLoading,_that.isComplete,_that.errorMessage);case _:
return orElse();
}
@@ -174,10 +175,10 @@ return $default(_that.deviceId,_that.soundOption,_that.isLoading,_that.errorMess
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String deviceId, String? soundOption, bool isLoading, String errorMessage) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String deviceId, String? soundOption, bool isLoading, bool isComplete, String errorMessage) $default,) {final _that = this;
switch (_that) {
case _SoundViewState():
return $default(_that.deviceId,_that.soundOption,_that.isLoading,_that.errorMessage);case _:
return $default(_that.deviceId,_that.soundOption,_that.isLoading,_that.isComplete,_that.errorMessage);case _:
throw StateError('Unexpected subclass');
}
@@ -194,10 +195,10 @@ return $default(_that.deviceId,_that.soundOption,_that.isLoading,_that.errorMess
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String deviceId, String? soundOption, bool isLoading, String errorMessage)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String deviceId, String? soundOption, bool isLoading, bool isComplete, String errorMessage)? $default,) {final _that = this;
switch (_that) {
case _SoundViewState() when $default != null:
return $default(_that.deviceId,_that.soundOption,_that.isLoading,_that.errorMessage);case _:
return $default(_that.deviceId,_that.soundOption,_that.isLoading,_that.isComplete,_that.errorMessage);case _:
return null;
}
@@ -209,12 +210,13 @@ return $default(_that.deviceId,_that.soundOption,_that.isLoading,_that.errorMess
class _SoundViewState implements SoundViewState {
const _SoundViewState({this.deviceId = '', this.soundOption, this.isLoading = true, this.errorMessage = ''});
const _SoundViewState({this.deviceId = '', this.soundOption, this.isLoading = true, this.isComplete = false, this.errorMessage = ''});
@override@JsonKey() final String deviceId;
@override final String? soundOption;
@override@JsonKey() final bool isLoading;
@override@JsonKey() final bool isComplete;
@override@JsonKey() final String errorMessage;
/// Create a copy of SoundViewState
@@ -227,16 +229,16 @@ _$SoundViewStateCopyWith<_SoundViewState> get copyWith => __$SoundViewStateCopyW
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SoundViewState&&(identical(other.deviceId, deviceId) || other.deviceId == deviceId)&&(identical(other.soundOption, soundOption) || other.soundOption == soundOption)&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage));
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SoundViewState&&(identical(other.deviceId, deviceId) || other.deviceId == deviceId)&&(identical(other.soundOption, soundOption) || other.soundOption == soundOption)&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.isComplete, isComplete) || other.isComplete == isComplete)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage));
}
@override
int get hashCode => Object.hash(runtimeType,deviceId,soundOption,isLoading,errorMessage);
int get hashCode => Object.hash(runtimeType,deviceId,soundOption,isLoading,isComplete,errorMessage);
@override
String toString() {
return 'SoundViewState(deviceId: $deviceId, soundOption: $soundOption, isLoading: $isLoading, errorMessage: $errorMessage)';
return 'SoundViewState(deviceId: $deviceId, soundOption: $soundOption, isLoading: $isLoading, isComplete: $isComplete, errorMessage: $errorMessage)';
}
@@ -247,7 +249,7 @@ abstract mixin class _$SoundViewStateCopyWith<$Res> implements $SoundViewStateCo
factory _$SoundViewStateCopyWith(_SoundViewState value, $Res Function(_SoundViewState) _then) = __$SoundViewStateCopyWithImpl;
@override @useResult
$Res call({
String deviceId, String? soundOption, bool isLoading, String errorMessage
String deviceId, String? soundOption, bool isLoading, bool isComplete, String errorMessage
});
@@ -264,11 +266,12 @@ class __$SoundViewStateCopyWithImpl<$Res>
/// Create a copy of SoundViewState
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? deviceId = null,Object? soundOption = freezed,Object? isLoading = null,Object? errorMessage = null,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? deviceId = null,Object? soundOption = freezed,Object? isLoading = null,Object? isComplete = null,Object? errorMessage = null,}) {
return _then(_SoundViewState(
deviceId: null == deviceId ? _self.deviceId : deviceId // ignore: cast_nullable_to_non_nullable
as String,soundOption: freezed == soundOption ? _self.soundOption : soundOption // ignore: cast_nullable_to_non_nullable
as String?,isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable
as bool,isComplete: null == isComplete ? _self.isComplete : isComplete // ignore: cast_nullable_to_non_nullable
as bool,errorMessage: null == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
as String,
));

View File

@@ -14,8 +14,8 @@ enum DeviceCommand {
rewards,
@JsonValue('SHUTDOWN')
shutdown,
@JsonValue('SOUND')
sound,
@JsonValue('SET_SOUND_MODE')
setSoundMode,
}
@freezed

View File

@@ -28,5 +28,5 @@ const _$DeviceCommandEnumMap = {
DeviceCommand.restart: 'RESTART',
DeviceCommand.rewards: 'REWARDS',
DeviceCommand.shutdown: 'SHUTDOWN',
DeviceCommand.sound: 'SOUND',
DeviceCommand.setSoundMode: 'SET_SOUND_MODE',
};