Skip to content

Commit

Permalink
Focus item when searching
Browse files Browse the repository at this point in the history
  • Loading branch information
ferraridamiano committed Jan 11, 2025
1 parent 6e4ec90 commit bb92daf
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 81 deletions.
14 changes: 10 additions & 4 deletions lib/app_router.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,14 @@ final routerProvider = Provider<GoRouter>(
path: '/conversions/:property',
pageBuilder: (context, state) {
final String property = state.pathParameters['property']!;
final propertyx = kebabStringToPropertyX(property);
return NoTransitionPage(child: ConversionPage(propertyx));
final propertyx = property.kebab2PropertyX();
final fragment = state.uri.fragment;
return NoTransitionPage(
child: ConversionPage(
propertyx,
focusedUnit: fragment == '' ? null : fragment,
),
);
},
),
GoRoute(
Expand All @@ -74,7 +80,7 @@ final routerProvider = Provider<GoRouter>(
path: ':property',
builder: (context, state) {
final String property = state.pathParameters['property']!;
final propertyx = kebabStringToPropertyX(property);
final propertyx = property.kebab2PropertyX();
return ReorderUnitsPage(
selectedProperty: propertyx,
isPropertySelected: true,
Expand All @@ -92,7 +98,7 @@ final routerProvider = Provider<GoRouter>(
path: ':property',
builder: (context, state) {
final String property = state.pathParameters['property']!;
final propertyx = kebabStringToPropertyX(property);
final propertyx = property.kebab2PropertyX();
return HideUnitsPage(
selectedProperty: propertyx,
isPropertySelected: true,
Expand Down
18 changes: 10 additions & 8 deletions lib/pages/app_scaffold.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,8 @@ class AppScaffold extends ConsumerWidget {
}

void clearAll(bool isDrawerFixed) {
final currentProperty = kebabStringToPropertyX(GoRouterState.of(context)
.uri
.toString()
.substring('/conversions/'.length));
final currentProperty =
GoRouterState.of(context).uri.pathSegments.last.kebab2PropertyX();
if (ref
.read(ConversionsNotifier.provider.notifier)
.shouldShowSnackbar(currentProperty)) {
Expand Down Expand Up @@ -63,13 +61,17 @@ class AppScaffold extends ConsumerWidget {

void openSearch() {
ref.read(PropertiesOrderNotifier.provider).whenData((orderList) async {
final selectedProperty = await showSearch<PROPERTYX?>(
final result = await showSearch(
context: context,
delegate: CustomSearchDelegate(orderList),
);
if (selectedProperty != null) {
final String targetPath =
'/conversions/${selectedProperty.toKebabCase()}';
if (result != null) {
final selectedProperty = result.$1;
final selectedUnit = result.$2;
var targetPath = '/conversions/${selectedProperty.toKebabCase()}';
if (selectedUnit != null) {
targetPath = '$targetPath#$selectedUnit';
}

if (context.mounted &&
GoRouterState.of(context).uri.toString() != targetPath) {
Expand Down
85 changes: 48 additions & 37 deletions lib/pages/conversion_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ import 'package:intl/intl.dart';

class ConversionPage extends ConsumerWidget {
final PROPERTYX property;
final String? focusedUnit;

const ConversionPage(this.property, {super.key});
const ConversionPage(this.property, {super.key, this.focusedUnit});

@override
Widget build(BuildContext context, WidgetRef ref) {
Expand Down Expand Up @@ -59,44 +60,54 @@ class ConversionPage extends ConsumerWidget {
}
}

UnitWidget unitWidgetBuilder(UnitData unitData) => UnitWidget(
tffKey: unitData.unit.name.toString(),
unitName: unitMap[unitData.unit.name]!,
unitSymbol: unitData.unit.symbol,
keyboardType: unitData.textInputType,
controller: unitData.tec,
validator: (String? input) {
if (input != null) {
if (input != '' && !unitData.getValidator().hasMatch(input)) {
return l10n.invalidCharacters;
}
}
return null;
},
onChanged: (String txt) {
if (txt.contains(',')) {
txt = txt.replaceAll(',', '.');
unitData.tec.text = txt;
}
if (txt.startsWith('.')) {
txt = '0$txt';
unitData.tec.text = txt;
UnitWidget unitWidgetBuilder(
UnitData unitData,
) {
final focusNode = FocusNode();
if (focusedUnit != null &&
focusedUnit == unitName2KebabCase(unitData.unit.name)) {
focusNode.requestFocus();
}
return UnitWidget(
tffKey: unitData.unit.name.toString(),
unitName: unitMap[unitData.unit.name]!,
unitSymbol: unitData.unit.symbol,
keyboardType: unitData.textInputType,
controller: unitData.tec,
focusNode: focusNode,
validator: (String? input) {
if (input != null) {
if (input != '' && !unitData.getValidator().hasMatch(input)) {
return l10n.invalidCharacters;
}
if (txt == '' || unitData.getValidator().hasMatch(txt)) {
var conversions = ref.read(ConversionsNotifier.provider.notifier);
//just numeral system uses a string for conversion
if (unitData.property == PROPERTYX.numeralSystems) {
conversions.convert(unitData, txt == "" ? null : txt, property);
} else {
conversions.convert(
unitData,
txt == "" ? null : double.parse(txt),
property,
);
}
}
return null;
},
onChanged: (String txt) {
if (txt.contains(',')) {
txt = txt.replaceAll(',', '.');
unitData.tec.text = txt;
}
if (txt.startsWith('.')) {
txt = '0$txt';
unitData.tec.text = txt;
}
if (txt == '' || unitData.getValidator().hasMatch(txt)) {
var conversions = ref.read(ConversionsNotifier.provider.notifier);
//just numeral system uses a string for conversion
if (unitData.property == PROPERTYX.numeralSystems) {
conversions.convert(unitData, txt == "" ? null : txt, property);
} else {
conversions.convert(
unitData,
txt == "" ? null : double.parse(txt),
property,
);
}
},
);
}
},
);
}

final unhiddenGridTiles = unhiddenUnitData.map(unitWidgetBuilder).toList();
final hiddenGridTiles = hiddenUnitData.map(unitWidgetBuilder).toList();
Expand Down
21 changes: 11 additions & 10 deletions lib/pages/search_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import 'package:converterpro/utils/utils_widgets.dart';
import 'package:flutter/material.dart';
import 'package:translations/app_localizations.dart';

class CustomSearchDelegate extends SearchDelegate<PROPERTYX?> {
class CustomSearchDelegate extends SearchDelegate<(PROPERTYX, String?)?> {
final List<PROPERTYX> orderList;

CustomSearchDelegate(this.orderList);
Expand All @@ -27,12 +27,13 @@ class CustomSearchDelegate extends SearchDelegate<PROPERTYX?> {
Widget buildSuggestions(BuildContext context) {
final Brightness brightness = Theme.of(context).brightness;

final List<SearchUnit> dataSearch = getSearchUnitsList((PROPERTYX result) {
close(context, result);
final List<SearchUnit> dataSearch =
getSearchUnitsList((PROPERTYX property, String? unitName) {
close(context, (property, unitName));
}, context);
final List<SearchGridTile> allConversions = initializeGridSearch(
(PROPERTYX result) {
close(context, result);
(PROPERTYX property) {
close(context, (property, null));
},
context,
brightness == Brightness.dark,
Expand Down Expand Up @@ -76,7 +77,7 @@ class CustomSearchDelegate extends SearchDelegate<PROPERTYX?> {

/// This method will return a List of [SearchUnit], needed in order to display the tiles in the search
List<SearchUnit> getSearchUnitsList(
void Function(PROPERTYX) onTap, BuildContext context) {
void Function(PROPERTYX, String?) onTap, BuildContext context) {
List<SearchUnit> searchUnitsList = [];
final propertyUiMap = getPropertyUiMap(context);
final unitUiMap = getUnitUiMap(context);
Expand All @@ -89,15 +90,15 @@ List<SearchUnit> getSearchUnitsList(
searchUnitsList.add(SearchUnit(
iconAsset: propertyImagePath,
unitName: propertyUi.name,
onTap: () => onTap(property.key),
onTap: () => onTap(property.key, null),
));
// Add units in search
searchUnitsList.addAll(
unitUiMap[propertyx]!.values.map(
unitUiMap[propertyx]!.entries.map(
(e) => SearchUnit(
iconAsset: propertyImagePath,
unitName: e,
onTap: () => onTap(propertyx),
unitName: e.value,
onTap: () => onTap(propertyx, unitName2KebabCase(e.key)),
),
),
);
Expand Down
8 changes: 4 additions & 4 deletions lib/utils/navigator_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ AppPage computeSelectedSection(BuildContext context) {

int? computeSelectedConversionPage(
BuildContext context, Map<PROPERTYX, int> inversePropertiesOrdering) {
final location = GoRouterState.of(context).uri.toString();
if (location.startsWith('/conversions')) {
return inversePropertiesOrdering[
kebabStringToPropertyX(location.split('/').last)];
final segments = GoRouterState.of(context).uri.pathSegments;

if (segments.isNotEmpty && segments[0] == 'conversions') {
return inversePropertiesOrdering[segments.last.kebab2PropertyX()];
}
return null;
}
23 changes: 16 additions & 7 deletions lib/utils/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -123,14 +123,23 @@ int color2Int(Color color) =>
_floatToInt8(color.g) << 8 |
_floatToInt8(color.b) << 0;

/// Converts PROPERTYX.digitalData to a kebab String like 'digital-data'
extension KebabCaseExtension on PROPERTYX {
String toKebabCase() => toString().split('.').last.replaceAllMapped(
extension on String {
String _toKebabCase() => replaceAllMapped(
RegExp(r'([A-Z])'), (match) => '-${match[0]!.toLowerCase()}');
}

PROPERTYX kebabStringToPropertyX(String string) {
final lowerCaseString = string.replaceAll('-', '').toLowerCase();
return PROPERTYX.values.firstWhere(
(e) => e.toString().toLowerCase() == 'propertyx.$lowerCaseString');
/// Converts PROPERTYX.digitalData to a kebab String like 'digital-data'
extension KebabCaseProperty on PROPERTYX {
String toKebabCase() => toString().split('.').last._toKebabCase();
}

extension KebabStringToPropertyX on String {
PROPERTYX kebab2PropertyX() {
final lowerCaseString = replaceAll('-', '').toLowerCase();
return PROPERTYX.values.firstWhere(
(e) => e.toString().toLowerCase() == 'propertyx.$lowerCaseString');
}
}

String unitName2KebabCase(dynamic unitName) =>
unitName.toString().split('.').last._toKebabCase();
15 changes: 4 additions & 11 deletions lib/utils/utils_widgets.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class UnitWidget extends StatefulWidget {
final String unitName;
final String? unitSymbol;
final void Function(String)? onChanged;
final FocusNode focusNode;

const UnitWidget({
super.key,
Expand All @@ -21,29 +22,21 @@ class UnitWidget extends StatefulWidget {
required this.unitName,
this.unitSymbol,
this.onChanged,
required this.focusNode,
});

@override
State<UnitWidget> createState() => _UnitWidgetState();
}

class _UnitWidgetState extends State<UnitWidget> {
FocusNode focusNode = FocusNode();

@override
void dispose() {
super.dispose();
focusNode.dispose();
}

@override
Widget build(BuildContext context) {
focusNode.addListener(() => setState(() {}));
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 15),
child: TextFormField(
key: ValueKey(widget.tffKey),
focusNode: focusNode,
focusNode: widget.focusNode,
style: const TextStyle(fontSize: 16.0),
keyboardType: widget.keyboardType,
controller: widget.controller,
Expand Down Expand Up @@ -77,7 +70,7 @@ class _UnitWidgetState extends State<UnitWidget> {
),
floatingLabelStyle: TextStyle(
fontSize: 20,
color: focusNode.hasFocus
color: widget.focusNode.hasFocus
? Theme.of(context).colorScheme.secondary
: null,
),
Expand Down

0 comments on commit bb92daf

Please sign in to comment.