From 885d75a18eef1b0da5297d801da7352cfb5cc468 Mon Sep 17 00:00:00 2001 From: Elena Nazarova Date: Wed, 11 Oct 2023 18:07:48 +0300 Subject: [PATCH] =?UTF-8?q?PSDK-978=20-=20=D0=AD=D0=BA=D1=80=D0=B0=D0=BD?= =?UTF-8?q?=20=D0=BD=D0=B0=D1=81=D1=82=D1=80=D0=BE=D0=B5=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main_screen/presentation/home.dart | 15 +- .../presentation/player_view.dart | 8 +- .../settings_screen/domain/settings_bloc.dart | 101 ++++++ .../domain/settings_event.dart | 71 +++++ .../domain/settings_state.dart | 254 +++++++++++++++ .../presentation/settings_view.dart | 293 ++++++------------ 6 files changed, 537 insertions(+), 205 deletions(-) create mode 100644 nut_player/example/lib/src/features/settings_screen/domain/settings_bloc.dart create mode 100644 nut_player/example/lib/src/features/settings_screen/domain/settings_event.dart create mode 100644 nut_player/example/lib/src/features/settings_screen/domain/settings_state.dart diff --git a/nut_player/example/lib/src/features/main_screen/presentation/home.dart b/nut_player/example/lib/src/features/main_screen/presentation/home.dart index 6d3a1c9..5c28dad 100644 --- a/nut_player/example/lib/src/features/main_screen/presentation/home.dart +++ b/nut_player/example/lib/src/features/main_screen/presentation/home.dart @@ -7,6 +7,7 @@ import 'package:nut_player_example/src/features/main_screen/presentation/buttons import 'package:nut_player_example/src/features/main_screen/presentation/json_view.dart'; import 'package:nut_player_example/src/features/main_screen/presentation/url_view.dart'; import 'package:nut_player_example/src/features/player_screen/presentation/player_view.dart'; +import 'package:nut_player_example/src/features/settings_screen/domain/settings_bloc.dart'; import '../../player_screen/domain/bloc/playerview_bloc.dart'; import '../../settings_screen/presentation/settings_view.dart'; @@ -92,7 +93,19 @@ class Home extends StatelessWidget { ); })); } else if (state is SettingState) { - Navigator.push(context, CupertinoPageRoute(builder: (_) { return const SettingsView(); })); + Navigator.push(context, CupertinoPageRoute(builder: (_) { + return BlocProvider( + create: (context) => SettingsBloc(), + child: BlocListener( + listener: (context, state) { + if (state is SettingsDismiss) { + Navigator.of(context).pop(); + } + }, + child: const SettingsView(), + ) + ); + })); } context.read().add(UrlResetEvent()); diff --git a/nut_player/example/lib/src/features/player_screen/presentation/player_view.dart b/nut_player/example/lib/src/features/player_screen/presentation/player_view.dart index e8a0bcb..d40c408 100644 --- a/nut_player/example/lib/src/features/player_screen/presentation/player_view.dart +++ b/nut_player/example/lib/src/features/player_screen/presentation/player_view.dart @@ -82,11 +82,11 @@ class _PlayerViewState extends State { fontSize: 13, fontWeight: FontWeight.w400)), ), - children: _buildOptionsWidgets(context, bloc)), + children: _buildOptionsWidgets(bloc)), CupertinoListSection.insetGrouped( margin: const EdgeInsets.symmetric(vertical: 0, horizontal: 20), hasLeading: false, - children: _buildStartPositionWidget(context, bloc) + children: _buildStartPositionWidget(bloc) ), CupertinoListSection.insetGrouped( hasLeading: false, @@ -147,7 +147,7 @@ class _PlayerViewState extends State { super.deactivate(); } - List _buildOptionsWidgets(BuildContext context, PlayerViewBloc bloc) { + List _buildOptionsWidgets(PlayerViewBloc bloc) { return PlayerViewController.playbackSettings.map((setting) { final selectedIndex = bloc.selectedIndex(setting); return OptionsView( @@ -166,7 +166,7 @@ class _PlayerViewState extends State { }).toList(); } - List _buildStartPositionWidget(BuildContext context, PlayerViewBloc bloc) { + List _buildStartPositionWidget(PlayerViewBloc bloc) { return [InputView( NumericOptionData( key: PlayerViewController.startPosition.key, diff --git a/nut_player/example/lib/src/features/settings_screen/domain/settings_bloc.dart b/nut_player/example/lib/src/features/settings_screen/domain/settings_bloc.dart new file mode 100644 index 0000000..974af82 --- /dev/null +++ b/nut_player/example/lib/src/features/settings_screen/domain/settings_bloc.dart @@ -0,0 +1,101 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:nut_player_example/src/common/models/option_data.dart'; + +part 'settings_event.dart'; +part 'settings_state.dart'; + +class SettingsBloc extends Bloc { + SettingsBloc() : super(SettingsInitialState.create()) { + on(_onDismissEvent); + on(_onSpeedChangedEvent); + on(_onVolumeChangedEvent); + on(_onBrightnessChangedEvent); + on(_onAutostartChangedEvent); + on(_onFullscreenChangedEvent); + on(_onPipChangedEvent); + on(_onSettingsChangedEvent); + on(_onColorChangedEvent); + on(_onQualityChangedEvent); + on(_onQualityNamingChangedEvent); + on(_onSubsChangedEvent); + on(_onStartPositionChangedEvent); + on(_onLoopChangedEvent); + } + + _onDismissEvent(DismissEvent event, Emitter emit) { + emit(SettingsDismiss()); + } + + _onSpeedChangedEvent(SpeedChangedEvent event, Emitter emit) { + final settingsState = state; + if (settingsState is! SettingsInitialState) { return; } + + final speedWithoutX = event.option.title.replaceAll(RegExp('x'), ''); + final speed = double.tryParse(speedWithoutX) ?? 1; + + emit(settingsState.copy(speed: speed)); + } + + _onVolumeChangedEvent(VolumeChangedEvent event, Emitter emit) { + final settingsState = state; + if (settingsState is! SettingsInitialState) { return; } + + final volume = double.parse(event.option.title); + + emit(settingsState.copy(volume: volume)); + } + + _onBrightnessChangedEvent(BrightnessChangedEvent event, Emitter emit) { + final settingsState = state; + if (settingsState is! SettingsInitialState) { return; } + + final brightness = double.parse(event.option.title); + + emit(settingsState.copy(brightness: brightness)); + } + + _onStartPositionChangedEvent(StartPositionChangedEvent event, Emitter emit) {} + _onQualityChangedEvent(QualityChangedEvent event, Emitter emit) {} + _onSubsChangedEvent(SubsChangedEvent event, Emitter emit) {} + _onQualityNamingChangedEvent(QualityNamingChangedEvent event, Emitter emit) {} + _onAutostartChangedEvent(AutostartChangedEvent event, Emitter emit) {} + _onLoopChangedEvent(LoopChangedEvent event, Emitter emit) {} + _onPipChangedEvent(PipChangedEvent event, Emitter emit) {} + _onSettingsChangedEvent(SettingsChangedEvent event, Emitter emit) {} + _onFullscreenChangedEvent(FullscreenChangedEvent event, Emitter emit) {} + _onColorChangedEvent(ColorChangedEvent event, Emitter emit) {} + + int selectedIndex(OptionDataContainer setting) { + if (setting.key == const Key('PlaybackOptionSpeedID')) { + return _selectedIndexForSpeed(setting.options); + } else if (setting.key == const Key('PlaybackOptionVolumeID')) { + return _selectedIndexForVolume(setting.options); + } else if (setting.key == const Key('PlaybackOptionBrightnessID')) { + return _selectedIndexForBrightness(setting.options); + } else { + return 0; + } + } + + int _selectedIndexForSpeed(List settings) { + final settingsState = state; + if (settingsState is! SettingsInitialState) { return 3; } + + return settings.indexWhere((element) => element.value == settingsState.speed.toString()); + } + + int _selectedIndexForVolume(List settings) { + final settingsState = state; + if (settingsState is! SettingsInitialState) { return 5; } + + return settings.indexWhere((element) => element.value == settingsState.volume.toString()); + } + + int _selectedIndexForBrightness(List settings) { + final settingsState = state; + if (settingsState is! SettingsInitialState) { return 5; } + + return settings.indexWhere((element) => element.value == settingsState.brightness.toString()); + } +} diff --git a/nut_player/example/lib/src/features/settings_screen/domain/settings_event.dart b/nut_player/example/lib/src/features/settings_screen/domain/settings_event.dart new file mode 100644 index 0000000..c955713 --- /dev/null +++ b/nut_player/example/lib/src/features/settings_screen/domain/settings_event.dart @@ -0,0 +1,71 @@ +part of 'settings_bloc.dart'; + +@immutable +abstract class SettingsEvent {} + +class DismissEvent extends SettingsEvent {} + +class SpeedChangedEvent extends SettingsEvent { + final OptionData option; + SpeedChangedEvent(this.option); +} + +class VolumeChangedEvent extends SettingsEvent { + final OptionData option; + VolumeChangedEvent(this.option); +} + +class BrightnessChangedEvent extends SettingsEvent { + final OptionData option; + BrightnessChangedEvent(this.option); +} + +class QualityChangedEvent extends SettingsEvent { + final OptionData option; + QualityChangedEvent(this.option); +} + +class QualityNamingChangedEvent extends SettingsEvent { + final OptionData option; + QualityNamingChangedEvent(this.option); +} + +class FullscreenChangedEvent extends SettingsEvent { + final OptionData option; + FullscreenChangedEvent(this.option); +} + +class ColorChangedEvent extends SettingsEvent { + final OptionData option; + ColorChangedEvent(this.option); +} + +class SubsChangedEvent extends SettingsEvent { + final bool isOn; + SubsChangedEvent(this.isOn); +} + +class PipChangedEvent extends SettingsEvent { + final bool isOn; + PipChangedEvent(this.isOn); +} + +class SettingsChangedEvent extends SettingsEvent { + final bool isOn; + SettingsChangedEvent(this.isOn); +} + +class AutostartChangedEvent extends SettingsEvent { + final bool isOn; + AutostartChangedEvent(this.isOn); +} + +class LoopChangedEvent extends SettingsEvent { + final bool isOn; + LoopChangedEvent(this.isOn); +} + +class StartPositionChangedEvent extends SettingsEvent { + final int value; + StartPositionChangedEvent(this.value); +} \ No newline at end of file diff --git a/nut_player/example/lib/src/features/settings_screen/domain/settings_state.dart b/nut_player/example/lib/src/features/settings_screen/domain/settings_state.dart new file mode 100644 index 0000000..2b99f3e --- /dev/null +++ b/nut_player/example/lib/src/features/settings_screen/domain/settings_state.dart @@ -0,0 +1,254 @@ +part of 'settings_bloc.dart'; + +enum FullscreenSettings { landscape, flexible, off } +enum SkinColor { white } +enum VideoQuality { auto, p2160, p1440, p1080, p720, p480, p360, p240, p144 } +enum VideoQualityNaming { common, rus, eng, resolution } +enum LogType { off, info, debug } + +sealed class SettingsState {} + +class SettingsDismiss extends SettingsState {} + +@immutable +class SettingsInitialState extends SettingsState { + final bool isSkinByDefault; + + final FullscreenSettings fullscreenSettings; + final bool isPipAvailable; + final bool isSettingsAvailable; + final SkinColor skinColor; + + final bool isAutostart; + final double volume; + final double brightness; + final double speed; + final VideoQualityNaming qualityNaming; + final VideoQuality quality; + final bool isSubtitlesAvailable; + final int start; + + final bool isLoop; + + final int manifest; + final int track; + final int chunk; + + final LogType log; + + SettingsInitialState({ + required this.isSkinByDefault, + required this.fullscreenSettings, + required this.isPipAvailable, + required this.isSettingsAvailable, + required this.skinColor, + required this.isAutostart, + required this.brightness, + required this.volume, + required this.speed, + required this.qualityNaming, + required this.quality, + required this.isSubtitlesAvailable, + required this.start, + required this.isLoop, + required this.manifest, + required this.track, + required this.chunk, + required this.log + }); + + SettingsInitialState copy({ + bool? isSkinByDefault, + + FullscreenSettings? fullscreenSettings, + bool? isPipAvailable, + bool? isSettingsAvailable, + SkinColor? skinColor, + + bool? isAutostart, + double? volume, + double? brightness, + double? speed, + VideoQualityNaming? qualityNaming, + VideoQuality? quality, + bool? isSubtitlesAvailable, + int? start, + + bool? isLoop, + + int? manifest, + int? track, + int? chunk, + + LogType? log + }) { + return SettingsInitialState( + isSkinByDefault: isSkinByDefault ?? this.isSkinByDefault, + fullscreenSettings: fullscreenSettings ?? this.fullscreenSettings, + isPipAvailable: isPipAvailable ?? this.isPipAvailable, + isSettingsAvailable: isSettingsAvailable ?? this.isSettingsAvailable, + skinColor: skinColor ?? this.skinColor, + isAutostart: isAutostart ?? this.isAutostart, + volume: volume ?? this.volume, + brightness: brightness ?? this.brightness, + speed: speed ?? this.speed, + qualityNaming: qualityNaming ?? this.qualityNaming, + quality: quality ?? this.quality, + isSubtitlesAvailable: isSubtitlesAvailable ?? this.isSubtitlesAvailable, + start: start ?? this.start, + isLoop: isLoop ?? this.isLoop, + manifest: manifest ?? this.manifest, + track: track ?? this.track, + chunk: chunk ?? this.chunk, + log: log ?? this.log + ); + } + + factory SettingsInitialState.create() { + return SettingsInitialState( + isSkinByDefault: true, + fullscreenSettings: FullscreenSettings.landscape, + isPipAvailable: false, + isSettingsAvailable: true, + skinColor: SkinColor.white, + isAutostart: false, + brightness: 0.5, + volume: 0.5, + speed: 1, + qualityNaming: VideoQualityNaming.common, + quality: VideoQuality.auto, + isSubtitlesAvailable: true, + start: 0, + isLoop: false, + manifest: 5000, + track: 3000, + chunk: 3000, + log: LogType.info); + } + + + static const skinSettings = [ + OptionData(key: Key('SkinOptionDefaultID'), title: 'По умолчанию', isSelected: true), + OptionData(key: Key('SkinOptionByUserID'), title: 'Свой') + ]; + + static final standardSkinSettings = [ + OptionDataContainer( + key: const Key('FullscreenID'), + title: 'Полноэкранный режим', + options: const [ + OptionData(key: Key('SkinStandardFullscreenAlbumID'), title: 'Альбомный'), + OptionData(key: Key('SkinStandardFullscreenFlexID'), title: 'Гибкий'), + OptionData(key: Key('SkinStandardFullscreenOffID'), title: 'Выкл.') + ] + ), + const OptionData(key: Key(''), title: 'Картинка в картинке'), + const OptionData(key: Key(''), title: 'Настройки', isSelected: true), + OptionDataContainer( + key: const Key('ColorID'), + title: 'Цвет', + options: const [ + OptionData(key: Key('SkinStandardColor1ID'), title: '#0D70D1'), + OptionData(key: Key('SkinStandardColor2ID'), title: '#000000'), + OptionData(key: Key('SkinStandardColor3ID'), title: '#FFFFFF') + ] + ) + ]; + + static final playbackOptions = [ + const OptionData(key: Key('PlaybackOptionAutostartID'), title: 'Автостарт'), + OptionDataContainer( + key: const Key('PlaybackOptionVolumeID'), + title: 'Громкость', + options: const [ + OptionData.withValueEqualTitle(Key('PlaybackOptionVolume00ID'), '0.0'), + OptionData.withValueEqualTitle(Key('PlaybackOptionVolume01ID'), '0.1'), + OptionData.withValueEqualTitle(Key('PlaybackOptionVolume02ID'), '0.2'), + OptionData.withValueEqualTitle(Key('PlaybackOptionVolume03ID'), '0.3'), + OptionData.withValueEqualTitle(Key('PlaybackOptionVolume04ID'), '0.4'), + OptionData.withValueEqualTitle(Key('PlaybackOptionVolume05ID'), '0.5'), + OptionData.withValueEqualTitle(Key('PlaybackOptionVolume06ID'), '0.6'), + OptionData.withValueEqualTitle(Key('PlaybackOptionVolume07ID'), '0.7'), + OptionData.withValueEqualTitle(Key('PlaybackOptionVolume08ID'), '0.8'), + OptionData.withValueEqualTitle(Key('PlaybackOptionVolume09ID'), '0.9'), + OptionData.withValueEqualTitle(Key('PlaybackOptionVolume10ID'), '1.0') + ], + onSelectedOption: (option) => VolumeChangedEvent(option) + ), + OptionDataContainer( + key: const Key('PlaybackOptionBrightnessID'), + title: 'Яркость', + options: const [ + OptionData.withValueEqualTitle(Key('PlaybackOptionVolume00ID'), '0.0'), + OptionData.withValueEqualTitle(Key('PlaybackOptionVolume01ID'), '0.1'), + OptionData.withValueEqualTitle(Key('PlaybackOptionVolume02ID'), '0.2'), + OptionData.withValueEqualTitle(Key('PlaybackOptionVolume03ID'), '0.3'), + OptionData.withValueEqualTitle(Key('PlaybackOptionVolume04ID'), '0.4'), + OptionData.withValueEqualTitle(Key('PlaybackOptionVolume05ID'), '0.5'), + OptionData.withValueEqualTitle(Key('PlaybackOptionVolume06ID'), '0.6'), + OptionData.withValueEqualTitle(Key('PlaybackOptionVolume07ID'), '0.7'), + OptionData.withValueEqualTitle(Key('PlaybackOptionVolume08ID'), '0.8'), + OptionData.withValueEqualTitle(Key('PlaybackOptionVolume09ID'), '0.9'), + OptionData.withValueEqualTitle(Key('PlaybackOptionVolume10ID'), '1.0') + ], + onSelectedOption: (option) => BrightnessChangedEvent(option) + ), + OptionDataContainer( + key: const Key('PlaybackOptionSpeedID'), + title: 'Скорость', + options: const [ + OptionData(key: Key('PlaybackOptionSpeed025xID'), title: '0.25x', value: '0.25'), + OptionData(key: Key('PlaybackOptionSpeed05xID'), title: '0.5x', value: '0.5'), + OptionData(key: Key('PlaybackOptionSpeed075xID'), title: '0.75x', value: '0.75'), + OptionData(key: Key('PlaybackOptionSpeedNormalID'), title: 'Обычная', value: '1.0'), + OptionData(key: Key('PlaybackOptionSpeed125xID'), title: '1.25x', value: '1.25'), + OptionData(key: Key('PlaybackOptionSpeed15xID'), title: '1.5x', value: '1.5'), + OptionData(key: Key('PlaybackOptionSpeed175xID'), title: '1.75x', value: '1.75'), + OptionData(key: Key('PlaybackOptionSpeed2xID'), title: '2x', value: '2.0') + ], + onSelectedOption: (option) => SpeedChangedEvent(option) + ), + OptionDataContainer( + key: const Key('PlaybackOptionQualityID'), + title: 'Качество', + options: const [ + OptionData.withValueEqualTitle(Key('PlaybackOptionQualityAutoID'), 'Авто'), + OptionData.withValueEqualTitle(Key('PlaybackOptionQuality4kID'), '4K'), + OptionData.withValueEqualTitle(Key('PlaybackOptionQuality1440pID'), '1440p Ultra HD'), + OptionData.withValueEqualTitle(Key('PlaybackOptionQuality1080pID'), '1080p FHD'), + OptionData.withValueEqualTitle(Key('PlaybackOptionQuality720pID'), '720p HD'), + OptionData.withValueEqualTitle(Key('PlaybackOptionQuality480pID'), '480p'), + OptionData.withValueEqualTitle(Key('PlaybackOptionQuality360pID'), '360p'), + OptionData.withValueEqualTitle(Key('PlaybackOptionQuality240pID'), '240p'), + OptionData.withValueEqualTitle(Key('PlaybackOptionQuality144pID'), '144p') + ] + ), + OptionDataContainer( + key: const Key('PlaybackOptionQualityNamingID'), + title: 'Название качества', + options: const [ + OptionData(key: Key('PlaybackOptionQualityNameCommonID'), title: 'Common'), + OptionData(key: Key('PlaybackOptionQualityNameRusID'), title: 'Russian'), + OptionData(key: Key('PlaybackOptionQualityNameEngID'), title: 'English'), + OptionData(key: Key('PlaybackOptionQualityNameResolutionID'), title: 'Resolution') + ] + ), + const OptionData(key: Key('PlaybackOptionSubtitlesID'), title: 'Субтитры', isSelected: true), + const NumericOptionData(key: Key('PlaybackOptionStartPositionID'), title: 'Стартовая позиция', value: 0) + ]; + + static const extraOption = OptionData(key: Key('ExtraOptionLoopID'), title: 'Зацикленность'); + + static const timeoutsOptions = [ + NumericOptionData(key: Key('TimeoutsOptionManifestID'), title: 'Манифест (мс)', value: 5000), + NumericOptionData(key: Key('TimeoutsOptionTrackID'), title: 'Трек (мс)', value: 3000), + NumericOptionData(key: Key('TimeoutsOptionChunkID'), title: 'Сегмент (мс)', value: 3000) + ]; + + static const logOptions = { + "LogType.off": OptionData(key: Key('LogOptionOffId'), title: 'Выкл.'), + "LogType.info": OptionData(key: Key('LogOptionInfoID'), title: 'Инфо.'), + "LogType.debug": OptionData(key: Key('LogOptionDebugID'), title: 'Отладка') + }; +} + diff --git a/nut_player/example/lib/src/features/settings_screen/presentation/settings_view.dart b/nut_player/example/lib/src/features/settings_screen/presentation/settings_view.dart index 8e05f5e..3c701ba 100644 --- a/nut_player/example/lib/src/features/settings_screen/presentation/settings_view.dart +++ b/nut_player/example/lib/src/features/settings_screen/presentation/settings_view.dart @@ -1,124 +1,18 @@ import 'package:flutter/cupertino.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:nut_player_example/src/common/models/option_data.dart'; +import 'package:nut_player_example/src/common/views/checkmark_list_option.dart'; //import 'package:nut_player_example/src/common/views/checkmark_list_option.dart'; import 'package:nut_player_example/src/common/views/input_view.dart'; -//import 'package:nut_player_example/src/common/views/options_view.dart'; +import 'package:nut_player_example/src/features/settings_screen/domain/settings_bloc.dart'; +import 'package:nut_player_example/src/common/views/options_view.dart'; +import 'package:nut_player_example/src/features/settings_screen/presentation/toggle_view.dart'; //import 'package:nut_player_example/src/features/settings_screen/presentation/toggle_view.dart'; -enum LogType { off, info, debug } +class SettingsView extends StatelessWidget { -class SettingsView extends StatefulWidget { const SettingsView({super.key}); - @override - State createState() => _SettingsViewState(); -} - -class _SettingsViewState extends State { - // final List _skinOptions = const [ - // OptionData(key: Key('SkinOptionDefaultID'), title: 'По умолчанию', isSelected: true), - // OptionData(key: Key('SkinOptionByUserID'), title: 'Свой') - // ]; - // - // final List _standardSkinOptions = const [ - // OptionData(key: Key('SkinStandardOptionFullscreenID'), title: 'Полноэкранный режим'), - // OptionData(key: Key('SkinStandardOptionPipID'), title: 'Картинка в картинке', isSelected: true), - // OptionData(key: Key('SkinStandardOptionSettingsID'), title: 'Настройки', isSelected: true), - // OptionData(key: Key('SkinStandardOptionColorID'), title: 'Цвет') - // ]; - - // final List _fullscreen = const [ - // OptionData(key: Key('SkinStandardFullscreenAlbumID'), title: 'Альбомный', isSelected: true), - // OptionData(key: Key('SkinStandardFullscreenFlexID'), title: 'Гибкий'), - // OptionData(key: Key('SkinStandardFullscreenOffID'), title: 'Выкл.') - // ]; - // - // final List _colors = const [ - // OptionData(key: Key('SkinStandardColor1ID'), title: '#0D70D1', isSelected: true), - // OptionData(key: Key('SkinStandardColor2ID'), title: '#000000'), - // OptionData(key: Key('SkinStandardColor3ID'), title: '#FFFFFF') - // ]; - - // final List _playbackOptions = const [ - // OptionData(key: Key('PlaybackOptionAutostartID'), title: 'Автостарт'), - // OptionData(key: Key('PlaybackOptionVolumeID'), title: 'Громкость'), - // OptionData(key: Key('PlaybackOptionBrightnessID'), title: 'Яркость'), - // OptionData(key: Key('PlaybackOptionSpeedID'), title: 'Скорость'), - // OptionData(key: Key('PlaybackOptionQualityNamingID'), title: 'Название качества'), - // OptionData(key: Key('PlaybackOptionQualityID'), title: 'Качество'), - // OptionData(key: Key('PlaybackOptionSubtitlesID'), title: 'Субтитры', isSelected: true) - // ]; - - //final NumericOptionData _startPositionOption = const NumericOptionData(key: Key('PlaybackOptionStartPositionID'), title: 'Стартовая позиция', value: 0); - - //final OptionData _extraOption = const OptionData(key: Key('ExtraOptionLoopID'), title: 'Зацикленность'); - - LogType _currentLogType = LogType.info; - - // final List _volumeOptions = const [ - // OptionData(key: Key('PlaybackOptionVolume00ID'), title: '0.0'), - // OptionData(key: Key('PlaybackOptionVolume01ID'), title: '0.1'), - // OptionData(key: Key('PlaybackOptionVolume02ID'), title: '0.2'), - // OptionData(key: Key('PlaybackOptionVolume03ID'), title: '0.3'), - // OptionData(key: Key('PlaybackOptionVolume04ID'), title: '0.4'), - // OptionData(key: Key('PlaybackOptionVolume05ID'), title: '0.5', isSelected: true), - // OptionData(key: Key('PlaybackOptionVolume06ID'), title: '0.6'), - // OptionData(key: Key('PlaybackOptionVolume07ID'), title: '0.7'), - // OptionData(key: Key('PlaybackOptionVolume08ID'), title: '0.8'), - // OptionData(key: Key('PlaybackOptionVolume09ID'), title: '0.9'), - // OptionData(key: Key('PlaybackOptionVolume10ID'), title: '1.0') - // ]; - - // final List _brightnessOptions = const [ - // OptionData(key: Key('PlaybackOptionBrightness00ID'), title: '0.0'), - // OptionData(key: Key('PlaybackOptionBrightness01ID'), title: '0.1'), - // OptionData(key: Key('PlaybackOptionBrightness02ID'), title: '0.2'), - // OptionData(key: Key('PlaybackOptionBrightness03ID'), title: '0.3'), - // OptionData(key: Key('PlaybackOptionBrightness04ID'), title: '0.4'), - // OptionData(key: Key('PlaybackOptionBrightness05ID'), title: '0.5', isSelected: true), - // OptionData(key: Key('PlaybackOptionBrightness06ID'), title: '0.6'), - // OptionData(key: Key('PlaybackOptionBrightness07ID'), title: '0.7'), - // OptionData(key: Key('PlaybackOptionBrightness08ID'), title: '0.8'), - // OptionData(key: Key('PlaybackOptionBrightness09ID'), title: '0.9'), - // OptionData(key: Key('PlaybackOptionBrightness10ID'), title: '1.0') - // ]; - - // final List _speedOptions = const [ - // OptionData(key: Key('PlaybackOptionSpeed025xID'), title: '0.25x'), - // OptionData(key: Key('PlaybackOptionSpeed05xID'), title: '0.5x'), - // OptionData(key: Key('PlaybackOptionSpeed075xID'), title: '0.75x'), - // OptionData(key: Key('PlaybackOptionSpeedNormalID'), title: 'Обычная', isSelected: true), - // OptionData(key: Key('PlaybackOptionSpeed125xID'), title: '1.25x'), - // OptionData(key: Key('PlaybackOptionSpeed15xID'), title: '1.5x'), - // OptionData(key: Key('PlaybackOptionSpeed175xID'), title: '1.75x'), - // OptionData(key: Key('PlaybackOptionSpeed2xID'), title: '2x'), - // ]; - - // final List _qualityOptions = const [ - // OptionData(key: Key('PlaybackOptionQualityAutoID'), title: 'Авто', isSelected: true), - // OptionData(key: Key('PlaybackOptionQuality4kID'), title: '4K'), - // OptionData(key: Key('PlaybackOptionQuality1440pID'), title: '1440p Ultra HD'), - // OptionData(key: Key('PlaybackOptionQuality1080pID'), title: '1080p FHD'), - // OptionData(key: Key('PlaybackOptionQuality720pID'), title: '720p HD'), - // OptionData(key: Key('PlaybackOptionQuality480pID'), title: '480p'), - // OptionData(key: Key('PlaybackOptionQuality360pID'), title: '360p'), - // OptionData(key: Key('PlaybackOptionQuality240pID'), title: '240p'), - // OptionData(key: Key('PlaybackOptionQuality144pID'), title: '144p') - // ]; - - // final List _qualityNamingOptions = const [ - // OptionData(key: Key('PlaybackOptionQualityNameCommonID'), title: 'Common', isSelected: true), - // OptionData(key: Key('PlaybackOptionQualityNameRusID'), title: 'Russian'), - // OptionData(key: Key('PlaybackOptionQualityNameEngID'), title: 'English'), - // OptionData(key: Key('PlaybackOptionQualityNameResolutionID'), title: 'Resolution') - // ]; - - final List _timeoutsOptions = const [ - NumericOptionData(key: Key('TimeoutsOptionManifestID'), title: 'Манифест (мс)', value: 5000), - NumericOptionData(key: Key('TimeoutsOptionTrackID'), title: 'Трек (мс)', value: 3000), - NumericOptionData(key: Key('TimeoutsOptionChunkID'), title: 'Сегмент (мс)', value: 3000) - ]; - @override Widget build(BuildContext context) { return CupertinoPageScaffold( @@ -128,14 +22,20 @@ class _SettingsViewState extends State { middle: const Text('Настройки', style: TextStyle(decoration: TextDecoration.none, color: CupertinoColors.black, fontWeight: FontWeight.w600)), leading: CupertinoNavigationBarBackButton( previousPageTitle: 'Назад', - onPressed: () { Navigator.of(context).pop(); } + onPressed: () { + final bloc = context.read(); + bloc.add(DismissEvent()); + } ), padding: const EdgeInsetsDirectional.all(0), backgroundColor: CupertinoColors.white, ), child: SafeArea( child: SingleChildScrollView( - child: Column( + child: BlocBuilder( + builder: (context, state) { + final bloc = context.read(); + return Column( children: [ // НАСТРОЙКИ СКИНА CupertinoListSection.insetGrouped( @@ -146,12 +46,11 @@ class _SettingsViewState extends State { style: const TextStyle(decoration: TextDecoration.none, color: CupertinoColors.systemGrey, fontSize: 13, fontWeight: FontWeight.w400) ), ), - children: const [] - // [..._skinOptions.map((value) { - // return CheckmarkListOption( - // value, false, () {}, - // ); - // }).toList()] + children: [...SettingsInitialState.skinSettings.map((value) { + return CheckmarkListOption( + value, value.isSelected, () {}, + ); + }).toList()] ), // НАСТРОЙКИ СТАНДАРТНОГО СКИНА @@ -163,16 +62,7 @@ class _SettingsViewState extends State { style: const TextStyle(decoration: TextDecoration.none, color: CupertinoColors.systemGrey, fontSize: 13, fontWeight: FontWeight.w400) ), ), - children: const [] - //[..._standardSkinOptions.map((value) { - // if (value.key == const Key('SkinStandardOptionFullscreenID')) { - // return OptionsView(value.title, _fullscreen); - // } else if (value.key == const Key('SkinStandardOptionColorID')) { - // return OptionsView(value.title, _colors); - // } else { - //return ToggleView(value); - // } - //}).toList()] + children: _buildSettingsWidgets(SettingsInitialState.standardSkinSettings, bloc) ), // ВОСПРОИЗВЕДЕНИЕ @@ -184,26 +74,7 @@ class _SettingsViewState extends State { style: const TextStyle(decoration: TextDecoration.none, color: CupertinoColors.systemGrey, fontSize: 13, fontWeight: FontWeight.w400) ), ), - children: const [] - //[..._playbackOptions.map((value) { - // if (value.key == const Key('PlaybackOptionVolumeID')) { - // return OptionsView(value.title, _volumeOptions); - // } else if (value.key == const Key('PlaybackOptionBrightnessID')) { - // return OptionsView(value.title, _brightnessOptions); - // } else if (value.key == const Key('PlaybackOptionSpeedID')) { - // return OptionsView(value.title, _speedOptions); - // } else if (value.key == const Key('PlaybackOptionQualityID')) { - // return OptionsView(value.title, _qualityOptions); - // } else if (value.key == const Key('PlaybackOptionQualityNamingID')) { - // return OptionsView(value.title, _qualityNamingOptions); - // } else if (value.key == const Key('PlaybackOptionStartPositionID')) { - // return ToggleView(value); - // } else { - //return ToggleView(value); - // } - //}).toList() - //+ [InputView(_startPositionOption)] - //] + children: _buildSettingsWidgets(SettingsInitialState.playbackOptions, bloc) ), // ДОПОЛНИТЕЛЬНО @@ -221,7 +92,7 @@ class _SettingsViewState extends State { style: TextStyle(decoration: TextDecoration.none, color: CupertinoColors.systemGrey, fontSize: 12, fontWeight: FontWeight.w400) ), ), - children: const []//[ToggleView(_extraOption)] + children: const [ToggleView(SettingsInitialState.extraOption)] ), // ЗАДЕРЖКИ @@ -233,7 +104,7 @@ class _SettingsViewState extends State { style: const TextStyle(decoration: TextDecoration.none, color: CupertinoColors.systemGrey, fontSize: 13, fontWeight: FontWeight.w400) ), ), - children: [..._timeoutsOptions.map((value) { + children: [...SettingsInitialState.timeoutsOptions.map((value) { return InputView(value); }).toList()] ), @@ -254,52 +125,7 @@ class _SettingsViewState extends State { color: CupertinoColors.systemGrey3, border: Border.all(color: CupertinoColors.systemGrey3) ), - child: CupertinoSlidingSegmentedControl( - backgroundColor: CupertinoColors.extraLightBackgroundGray, - groupValue: _currentLogType, - onValueChanged: (LogType? value) { - if (value != null) { - setState(() { - _currentLogType = value; - }); - } - }, - children: const { - LogType.off: Padding( - key: Key('LogOffSegmentElementID'), - padding: EdgeInsets.symmetric(vertical: 6), - child: Text('Выкл.', - style: TextStyle( - decoration: TextDecoration.none, - fontSize: 16, - color: CupertinoColors.black, - fontWeight: FontWeight.normal) - ), - ), - LogType.info: Padding( - key: Key('LogInfoSegmentElementID'), - padding: EdgeInsets.symmetric(vertical: 6), - child: Text('Инфо', - style: TextStyle( - decoration: TextDecoration.none, - fontSize: 16, - color: CupertinoColors.black, - fontWeight: FontWeight.normal) - ), - ), - LogType.debug: Padding( - key: Key('LogDebugSegmentElementID'), - padding: EdgeInsets.symmetric(vertical: 6), - child: Text('Отладка', - style: TextStyle( - decoration: TextDecoration.none, - fontSize: 16, - color: CupertinoColors.black, - fontWeight: FontWeight.normal) - ), - ) - }, - ) + child: _buildLog(context) ), ] ), @@ -322,7 +148,10 @@ class _SettingsViewState extends State { padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16), child: const Text('Проверка падения приложения', style: TextStyle(decoration: TextDecoration.none, color: CupertinoColors.black, fontSize: 17, fontWeight: FontWeight.w400)), - onPressed: (){ final value = const []; print(value[7]); } + onPressed: () { + const value = []; + value[7]; + } ) ) ] @@ -335,9 +164,73 @@ class _SettingsViewState extends State { style: TextStyle(decoration: TextDecoration.none, color: CupertinoColors.systemGrey, fontSize: 13, fontWeight: FontWeight.w400)) ) ] - ) + ); + }, + ) ) ) ); } + + List _buildSettingsWidgets(List objects, SettingsBloc bloc) { + return [...objects.map((setting) { + if (setting is OptionDataContainer) { + final selectedIndex = bloc.selectedIndex(setting); + return OptionsView( + setting.title, + setting.options, + selectedIndex, + (selectedIndex) { + final selectedOption = setting.options[selectedIndex]; + final event = setting.onSelectedOption?.call(selectedOption); + if (event != null) { + bloc.add(event); + } + }, + key: setting.key, + ); + } else if (setting is OptionData) { + return ToggleView(setting); + } else if (setting is NumericOptionData) { + return InputView(setting); + } else { + return const Text('not implemented'); + } + }).toList()]; + } + + Widget? _buildLog(BuildContext context) { + final bloc = context.read(); + final settingsState = bloc.state; + if (settingsState is! SettingsInitialState) { return null; } + + return CupertinoSlidingSegmentedControl( + backgroundColor: CupertinoColors.extraLightBackgroundGray, + groupValue: settingsState.log, + onValueChanged: (LogType? value) { + if (value != null) { + // менять состояние + } + }, + children: { + LogType.off: _buildLogSegment(SettingsInitialState.logOptions[LogType.off.toString()]!), + LogType.info: _buildLogSegment(SettingsInitialState.logOptions[LogType.info.toString()]!), + LogType.debug: _buildLogSegment(SettingsInitialState.logOptions[LogType.debug.toString()]!), + }, + ); + } + + Padding _buildLogSegment(OptionData data) { + return Padding( + key: data.key, + padding: const EdgeInsets.symmetric(vertical: 6), + child: Text(data.title, + style: const TextStyle( + decoration: TextDecoration.none, + fontSize: 16, + color: CupertinoColors.black, + fontWeight: FontWeight.normal) + ), + ); + } }