Skip to content

Commit

Permalink
Migrates to a modal-based search to avoid quirks related to fullscree…
Browse files Browse the repository at this point in the history
…n search
  • Loading branch information
jankratochvilcz committed Jan 7, 2024
1 parent 840c2db commit 9529853
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 171 deletions.
6 changes: 5 additions & 1 deletion lib/models/slices/navigation/overlays_service.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:kotobaten/consts/paddings.dart';
import 'package:kotobaten/consts/shapes.dart';
import 'package:kotobaten/models/slices/navigation/overlays_repository.dart';

Expand All @@ -19,7 +20,10 @@ class OverlaysService {
context: context,
isScrollControlled: true,
shape: defaultBottomSheetShape,
builder: builder)
builder: (context) => Padding(
padding: allPadding(PaddingType.standard),
child: builder(context),
))
: showDialog(
context: context,
builder: (localContext) => AlertDialog(
Expand Down
129 changes: 0 additions & 129 deletions lib/views/organisms/search/universal_search.dart

This file was deleted.

77 changes: 77 additions & 0 deletions lib/views/organisms/search/universal_search_v3.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:kotobaten/consts/colors.dart';
import 'package:kotobaten/consts/paddings.dart';
import 'package:kotobaten/views/organisms/search/search_results.dart';
import 'package:kotobaten/views/screens/search.model.dart';
import 'package:kotobaten/views/screens/search.viewmodel.dart';

class UniversalSearchV3 extends HookConsumerWidget {
const UniversalSearchV3({super.key});

@override
Widget build(BuildContext context, WidgetRef ref) {
final viewModel = ref.read(searchViewModelProvider.notifier);
final model = ref.watch(searchViewModelProvider);

var loadedCounter = "No results";
if (model is SearchModelLoaded) {
if (model.dictionaryCards.isNotEmpty && model.cards.isEmpty) {
loadedCounter = "${model.dictionaryCards.length} dictionary results";
}

if (model.cards.isNotEmpty && model.dictionaryCards.isEmpty) {
loadedCounter = "${model.cards.length} collection results";
}

if (model.cards.isNotEmpty && model.dictionaryCards.isNotEmpty) {
loadedCounter =
"${model.cards.length} collection + ${model.dictionaryCards.length} dictionary results";
}
}

return Column(
children: [
Padding(
padding: bottomPadding(PaddingType.standard),
child: TextField(
autofocus: true,
controller: viewModel.searchTermController,
decoration: InputDecoration(
counter: viewModel is SearchModelLoading
? SizedBox.fromSize(
size: const Size(12, 12),
child: const CircularProgressIndicator(strokeWidth: 1),
)
: (viewModel is SearchModelInitial
? null
: Text(loadedCounter)),
labelText: "Universal search",
border: const UnderlineInputBorder(),
suffixIcon: const Icon(Icons.search),
),
onSubmitted: (value) {
// Implement your search function here
},
),
),
Expanded(
child: viewModel.searchTermController.text.isNotEmpty
? (model is SearchModelLoaded &&
(model.cards.isNotEmpty ||
model.dictionaryCards.isNotEmpty)
? const SearchResults()
: Center(
child: Text(
"No results.",
style: TextStyle(color: getDescriptionColor(context)),
)))
: Center(
child: Text(
"Search the dictionary and your collection, all at once.",
style: TextStyle(color: getDescriptionColor(context)),
)))
],
);
}
}
29 changes: 11 additions & 18 deletions lib/views/screens/home.view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import 'package:kotobaten/views/molecules/goals_card.dart';
import 'package:kotobaten/views/organisms/home/card_collect.dart';
import 'package:kotobaten/views/organisms/home/card_learn.dart';
import 'package:kotobaten/views/organisms/loading.dart';
import 'package:kotobaten/views/organisms/search/universal_search.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';

@RoutePage(name: 'HomeRoute')
Expand Down Expand Up @@ -43,23 +42,17 @@ class HomeView extends HookConsumerWidget {
return Padding(
padding: allPadding(PaddingType.xLarge),
child: MediaQuery.of(context).size.width >= minimumDesktopSize
? Stack(children: [
const Positioned(
top: 0,
right: 0,
child: SizedBox(width: 300, child: UniversalSearch())),
Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const DesktopCard(GoalsCard()),
DesktopCard(
CardLearn(userModelInitialized.user, goToPractice)),
const DesktopCard(CardCollect()),
],
))
])
? Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const DesktopCard(GoalsCard()),
DesktopCard(
CardLearn(userModelInitialized.user, goToPractice)),
const DesktopCard(CardCollect()),
],
))
: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expand Down
15 changes: 9 additions & 6 deletions lib/views/screens/search.viewmodel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,15 @@ class SearchViewModel extends StateNotifier<SearchModel> {

SearchViewModel(this._apiService) : super(SearchModel.initial(true)) {
searchTermController
.addListener(() => _searchTermUpdates.add(searchTermController.text));
.addListener(() => executeSearch(searchTermController.text));

searchController
.addListener(() => _searchTermUpdates.add(searchController.text));
searchController.addListener(() => executeSearch(searchController.text));

_searchTermUpdates.stream
.distinct()
.where((x) => x.length > 1)
.where((x) => x.length > 0)
.debounceTime(const Duration(milliseconds: 300))
.forEach(executeSearch);
.forEach(_executeSearch);

_searchTextFocus.addListener(
() => _searchTextFocusUpdates.add(_searchTextFocus.hasFocus));
Expand All @@ -52,7 +51,11 @@ class SearchViewModel extends StateNotifier<SearchModel> {
baseOffset: 0, extentOffset: _searchTermController.text.length);
}

Future executeSearch(String text) async {
void executeSearch(String text) {
_searchTermUpdates.add(text);
}

Future _executeSearch(String text) async {
state = SearchModel.loading(state.searchFocused);
final result = await _apiService.search(text.trim());
state = SearchModel.loaded(state.searchFocused, result.query, result.cards,
Expand Down
58 changes: 41 additions & 17 deletions lib/views/templates/scaffold_default.view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import 'package:kotobaten/consts/navigation.dart';
import 'package:kotobaten/consts/paddings.dart';
import 'package:kotobaten/consts/sizes.dart';
import 'package:kotobaten/models/slices/navigation/overlays_repository.dart';
import 'package:kotobaten/models/slices/navigation/overlays_service.dart';
import 'package:kotobaten/services/navigation_service.dart';
import 'package:kotobaten/views/organisms/search/universal_search.dart';
import 'package:kotobaten/views/organisms/search/universal_search_v3.dart';
import 'package:kotobaten/views/templates/fab_selector.dart';

enum HelpMenuItems { about, androidApp, iosApp, help }
Expand Down Expand Up @@ -55,8 +56,8 @@ class ScaffoldDefault extends HookConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
final navigationService = ref.read(navigationServiceProvider);
final overlaysModel = ref.watch(overlaysRepositoryProvider);
final overlaysService = ref.read(overlaysServiceProvider);
final selectedNavigationIndex = useState(0);
final renderUniversalSearch = useState(false);

final navigationItems = getNavigationItems(context);
final homeNavigation = navigationItems[NavigationItemType.home]!;
Expand All @@ -79,7 +80,15 @@ class ScaffoldDefault extends HookConsumerWidget {
Theme.of(context).colorScheme.secondary,
child: searchNavigation.icon,
onPressed: () {
renderUniversalSearch.value = true;
overlaysService.showOverlay(
context,
(context) => SizedBox.fromSize(
size: Size(
MediaQuery.of(context).size.width,
MediaQuery.of(context).size.height /
3 *
2),
child: const UniversalSearchV3()));
})
: null));

Expand Down Expand Up @@ -157,10 +166,34 @@ class ScaffoldDefault extends HookConsumerWidget {
child: Container(
constraints:
const BoxConstraints(maxWidth: 40),
child: const Image(
image: AssetImage(
'assets/logos/logo_square_white.png'),
))),
child: Column(children: [
Container(
constraints:
const BoxConstraints(maxWidth: 36),
child: const Image(
image: AssetImage(
'assets/logos/logo_square_white.png'),
)),
Padding(
padding:
topPadding(PaddingType.standard),
child: IconButton.filled(
color: Theme.of(context)
.colorScheme
.onPrimary,
onPressed: () {
overlaysService.showOverlay(
context,
(context) =>
SizedBox.fromSize(
size: const Size(
600, 800),
child:
const UniversalSearchV3(),
));
},
icon: const Icon(Icons.search)))
]))),
groupAlignment: 0,
backgroundColor: navigationBackgroundColor,
destinations: [
Expand Down Expand Up @@ -212,16 +245,7 @@ class ScaffoldDefault extends HookConsumerWidget {
],
)
: Stack(
children: [
child,
if (renderUniversalSearch.value)
UniversalSearch(
forceOpenView: true,
onClosed: () {
renderUniversalSearch.value = false;
},
),
],
children: [child],
));
},
);
Expand Down

0 comments on commit 9529853

Please sign in to comment.