-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(digital-guide): add accessibility modes dialog
- Loading branch information
1 parent
8075640
commit dd576a5
Showing
12 changed files
with
433 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 11 additions & 1 deletion
12
lib/features/digital_guide_view/presentation/widgets/accessibility_button.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
67 changes: 67 additions & 0 deletions
67
...res/digital_guide_view/tabs/accessibility_dialog/business/accessibility_mode_service.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import "dart:async"; | ||
|
||
import "package:fast_immutable_collections/fast_immutable_collections.dart"; | ||
import "package:riverpod_annotation/riverpod_annotation.dart"; | ||
|
||
import "../data/accessibility_mode_repository.dart"; | ||
import "../data/modes.dart"; | ||
|
||
part "accessibility_mode_service.g.dart"; | ||
|
||
// if the mode has children, it will be calculated based on them | ||
// if the mode has a key, it will be calculated based on the repository | ||
@riverpod | ||
class AccessibilityModeService extends _$AccessibilityModeService { | ||
@override | ||
Future<bool> build(AccessibilityMode mode) async { | ||
return switch (mode) { | ||
ModeWithChildren() => _calculateModeWithChildrenState(mode), | ||
ModeWithKey() => ref.watch( | ||
accessibilityModeRepositoryProvider(mode).future, | ||
), | ||
}; | ||
} | ||
|
||
Future<void> setMode({required bool newValue}) async { | ||
final modeStronglyTyped = mode; // needed for typing system | ||
await switch (modeStronglyTyped) { | ||
ModeWithChildren() => | ||
_setModeWithChildrenState(modeStronglyTyped, newValue), | ||
ModeWithKey() => _setSingularModeState(modeStronglyTyped, newValue), | ||
}; | ||
} | ||
|
||
// true if any of its children are true | ||
Future<bool> _calculateModeWithChildrenState(ModeWithChildren mode) async { | ||
final submodesValues = await Future.wait( | ||
mode.children.map( | ||
(child) => ref.watch(accessibilityModeServiceProvider(child).future), | ||
), | ||
); | ||
return submodesValues.anyIs(true); | ||
} | ||
|
||
// sets all childrens' of the mode to newValue | ||
Future<void> _setModeWithChildrenState( | ||
ModeWithChildren mode, | ||
bool newValue, | ||
) async { | ||
for (final child in mode.children) { | ||
await ref | ||
.read(accessibilityModeServiceProvider(child).notifier) | ||
.setMode(newValue: newValue); | ||
} | ||
} | ||
|
||
// calls directly the repository | ||
Future<void> _setSingularModeState( | ||
ModeWithKey modeStronglyTyped, | ||
bool newValue, | ||
) { | ||
return ref | ||
.read( | ||
accessibilityModeRepositoryProvider(modeStronglyTyped).notifier, | ||
) | ||
.setMode(newValue: newValue); | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
lib/features/digital_guide_view/tabs/accessibility_dialog/business/top_level_modes.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import "../data/modes.dart"; | ||
|
||
final topLevelModes = [ | ||
const MotorImpairment(), | ||
const VisualImpairment(), | ||
const SensorySensitivity(), | ||
const CognitiveImpairment(), | ||
]; |
23 changes: 23 additions & 0 deletions
23
...ures/digital_guide_view/tabs/accessibility_dialog/data/accessibility_mode_repository.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import "dart:async"; | ||
|
||
import "package:riverpod_annotation/riverpod_annotation.dart"; | ||
|
||
import "../../../../../config/shared_prefs.dart"; | ||
import "modes.dart"; | ||
|
||
part "accessibility_mode_repository.g.dart"; | ||
|
||
@riverpod | ||
class AccessibilityModeRepository extends _$AccessibilityModeRepository { | ||
@override | ||
Future<bool> build(ModeWithKey mode) async { | ||
final prefs = await ref.watch(sharedPreferencesSingletonProvider.future); | ||
return prefs.getBool(mode.sharedPrefsKey) ?? false; | ||
} | ||
|
||
Future<void> setMode({required bool newValue}) async { | ||
state = AsyncValue.data(newValue); | ||
final prefs = await ref.watch(sharedPreferencesSingletonProvider.future); | ||
await prefs.setBool(mode.sharedPrefsKey, newValue); | ||
} | ||
} |
48 changes: 48 additions & 0 deletions
48
lib/features/digital_guide_view/tabs/accessibility_dialog/data/modes.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// https://dart.dev/language/class-modifiers#sealed | ||
sealed class AccessibilityMode { | ||
const AccessibilityMode(); | ||
} | ||
|
||
// this mode's state depends on the state of its children | ||
sealed class ModeWithChildren extends AccessibilityMode { | ||
const ModeWithChildren(this.children); | ||
final List<AccessibilityMode> children; | ||
} | ||
|
||
// this mode's state is stored locally in shared preferences | ||
sealed class ModeWithKey extends AccessibilityMode { | ||
const ModeWithKey(this.sharedPrefsKey); | ||
final String sharedPrefsKey; | ||
} | ||
|
||
class MotorImpairment extends ModeWithKey { | ||
const MotorImpairment() : super("_prefs_accessibility_motor_impairment"); | ||
} | ||
|
||
class Blind extends ModeWithKey { | ||
const Blind() : super("_prefs_accessibility_blind"); | ||
} | ||
|
||
class LowVision extends ModeWithKey { | ||
const LowVision() : super("_prefs_accessibility_low_vision"); | ||
} | ||
|
||
class SensorySensitivity extends ModeWithKey { | ||
const SensorySensitivity() | ||
: super("_prefs_accessibility_sensory_sensitivity"); | ||
} | ||
|
||
class CognitiveImpairment extends ModeWithKey { | ||
const CognitiveImpairment() | ||
: super("_prefs_accessibility_cognitive_impairment"); | ||
} | ||
|
||
class VisualImpairment extends ModeWithChildren { | ||
const VisualImpairment() | ||
: super( | ||
const [ | ||
LowVision(), | ||
Blind(), | ||
], | ||
); | ||
} |
18 changes: 18 additions & 0 deletions
18
...tures/digital_guide_view/tabs/accessibility_dialog/presentation/accessibility_dialog.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import "package:flutter/material.dart"; | ||
|
||
import "../../../../../utils/context_extensions.dart"; | ||
import "checkboxes_list.dart"; | ||
import "red_dialog.dart"; | ||
|
||
class AccessibilityDialog extends StatelessWidget { | ||
const AccessibilityDialog({super.key}); | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return RedDialog( | ||
title: context.localize.accessibility_profiles, | ||
subtitle: context.localize.you_can_adjust, | ||
child: const CheckboxesList(), | ||
); | ||
} | ||
} |
35 changes: 35 additions & 0 deletions
35
lib/features/digital_guide_view/tabs/accessibility_dialog/presentation/checkboxes_list.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import "package:flutter/material.dart"; | ||
import "package:flutter_hooks/flutter_hooks.dart"; | ||
|
||
import "../business/top_level_modes.dart"; | ||
import "../data/modes.dart"; | ||
import "mode_checkbox.dart"; | ||
|
||
class _SubModePadding extends Padding { | ||
const _SubModePadding({super.child}) | ||
: super( | ||
padding: const EdgeInsets.only(left: 25), | ||
); | ||
} | ||
|
||
class CheckboxesList extends HookWidget { | ||
const CheckboxesList({super.key}); | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return Column( | ||
children: [ | ||
for (final mode in topLevelModes) | ||
switch (mode) { | ||
ModeWithChildren() => Column( | ||
children: [ | ||
for (final subMode in mode.children) | ||
_SubModePadding(child: ModeCheckbox(subMode)), | ||
], | ||
), | ||
ModeWithKey() => ModeCheckbox(mode), | ||
}, | ||
], | ||
); | ||
} | ||
} |
17 changes: 17 additions & 0 deletions
17
lib/features/digital_guide_view/tabs/accessibility_dialog/presentation/labels.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import "package:flutter/material.dart"; | ||
|
||
import "../../../../../utils/context_extensions.dart"; | ||
import "../data/modes.dart"; | ||
|
||
extension AccessibilityModeLocalizationX on AccessibilityMode { | ||
String localizedLabel(BuildContext context) { | ||
return switch (this) { | ||
MotorImpairment() => context.localize.motorImpairment, | ||
VisualImpairment() => context.localize.visualImpairment, | ||
Blind() => context.localize.blind, | ||
LowVision() => context.localize.lowVision, | ||
SensorySensitivity() => context.localize.sensorySensitivity, | ||
CognitiveImpairment() => context.localize.cognitiveImpairment, | ||
}; | ||
} | ||
} |
40 changes: 40 additions & 0 deletions
40
lib/features/digital_guide_view/tabs/accessibility_dialog/presentation/mode_checkbox.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import "dart:async"; | ||
|
||
import "package:flutter/material.dart"; | ||
import "package:flutter_riverpod/flutter_riverpod.dart"; | ||
|
||
import "../../../../../theme/app_theme.dart"; | ||
import "../business/accessibility_mode_service.dart"; | ||
import "../data/modes.dart"; | ||
import "labels.dart"; | ||
|
||
class ModeCheckbox extends ConsumerWidget { | ||
const ModeCheckbox(this.mode, {super.key}); | ||
final AccessibilityMode mode; | ||
@override | ||
Widget build(BuildContext context, WidgetRef ref) { | ||
final value = ref.watch(accessibilityModeServiceProvider(mode)); | ||
|
||
// ignore: avoid_positional_boolean_parameters | ||
void onChanged(bool? value) { | ||
if (value != null) { | ||
unawaited( | ||
ref | ||
.read(accessibilityModeServiceProvider(mode).notifier) | ||
.setMode(newValue: value), | ||
); | ||
} | ||
} | ||
|
||
return CheckboxListTile( | ||
dense: true, | ||
controlAffinity: ListTileControlAffinity.leading, | ||
title: Text( | ||
mode.localizedLabel(context), | ||
style: context.aboutUsTheme.body, | ||
), | ||
value: value.value ?? false, | ||
onChanged: onChanged, | ||
); | ||
} | ||
} |
Oops, something went wrong.