increase min sdk and apply new formatter
This commit is contained in:
@@ -23,8 +23,9 @@ class SearchScreen extends HookConsumerWidget {
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final formKey = useMemoized(() => GlobalKey<FormState>());
|
||||
|
||||
final searchTextController =
|
||||
useTextEditingController(text: initialSearchText);
|
||||
final searchTextController = useTextEditingController(
|
||||
text: initialSearchText,
|
||||
);
|
||||
final searchFocusNode = useFocusNode();
|
||||
|
||||
final defaultSearchBang = ref.watch(
|
||||
@@ -35,16 +36,13 @@ class SearchScreen extends HookConsumerWidget {
|
||||
final activeBang = selectedBang.value ?? defaultSearchBang;
|
||||
final showBangIcon = useState(false);
|
||||
|
||||
ref.listen(
|
||||
selectedBangDataProvider(),
|
||||
(previous, next) {
|
||||
if (previous != next) {
|
||||
showBangIcon.value = true;
|
||||
}
|
||||
ref.listen(selectedBangDataProvider(), (previous, next) {
|
||||
if (previous != next) {
|
||||
showBangIcon.value = true;
|
||||
}
|
||||
|
||||
selectedBang.value = next;
|
||||
},
|
||||
);
|
||||
selectedBang.value = next;
|
||||
});
|
||||
|
||||
Future<void> submitSearch(String query) async {
|
||||
if (activeBang != null && (formKey.currentState?.validate() == true)) {
|
||||
@@ -78,12 +76,14 @@ class SearchScreen extends HookConsumerWidget {
|
||||
autofocus: true,
|
||||
onSubmitted: (value) async {
|
||||
if (value.isNotEmpty) {
|
||||
var newUrl =
|
||||
uri_parser.tryParseUrl(value, eagerParsing: true);
|
||||
var newUrl = uri_parser.tryParseUrl(
|
||||
value,
|
||||
eagerParsing: true,
|
||||
);
|
||||
|
||||
if (newUrl == null) {
|
||||
final defaultSearchBang = ref
|
||||
.read(selectedBangDataProvider()) ??
|
||||
final defaultSearchBang =
|
||||
ref.read(selectedBangDataProvider()) ??
|
||||
await ref.read(defaultSearchBangDataProvider.future);
|
||||
|
||||
newUrl = defaultSearchBang?.getUrl(value);
|
||||
@@ -108,23 +108,15 @@ class SearchScreen extends HookConsumerWidget {
|
||||
showSuggestions: true,
|
||||
),
|
||||
),
|
||||
const SliverToBoxAdapter(
|
||||
child: Divider(),
|
||||
),
|
||||
const SliverToBoxAdapter(child: Divider()),
|
||||
SearchTermSuggestions(
|
||||
searchTextController: searchTextController,
|
||||
activeBang: activeBang,
|
||||
submitSearch: submitSearch,
|
||||
),
|
||||
const SliverToBoxAdapter(
|
||||
child: Divider(),
|
||||
),
|
||||
TabSearch(
|
||||
searchTextController: searchTextController,
|
||||
),
|
||||
HistorySuggestions(
|
||||
searchTextController: searchTextController,
|
||||
),
|
||||
const SliverToBoxAdapter(child: Divider()),
|
||||
TabSearch(searchTextController: searchTextController),
|
||||
HistorySuggestions(searchTextController: searchTextController),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -31,24 +31,21 @@ class BangChips extends HookConsumerWidget {
|
||||
) {
|
||||
return showDialog<bool>(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: Text(
|
||||
'Reset usage frequency of $triggerName?',
|
||||
),
|
||||
content: const Text(
|
||||
'This will remove the Bang from quick select.',
|
||||
),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context, false),
|
||||
child: const Text('Cancel'),
|
||||
builder:
|
||||
(context) => AlertDialog(
|
||||
title: Text('Reset usage frequency of $triggerName?'),
|
||||
content: const Text('This will remove the Bang from quick select.'),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context, false),
|
||||
child: const Text('Cancel'),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context, true),
|
||||
child: const Text('Reset'),
|
||||
),
|
||||
],
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context, true),
|
||||
child: const Text('Reset'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -56,14 +53,11 @@ class BangChips extends HookConsumerWidget {
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final availableBangs = ref.watch(seamlessBangProviderProvider);
|
||||
|
||||
useListenableCallback(
|
||||
searchTextController,
|
||||
() {
|
||||
ref
|
||||
.read(seamlessBangProviderProvider.notifier)
|
||||
.search(searchTextController!.text);
|
||||
},
|
||||
);
|
||||
useListenableCallback(searchTextController, () {
|
||||
ref
|
||||
.read(seamlessBangProviderProvider.notifier)
|
||||
.search(searchTextController!.text);
|
||||
});
|
||||
|
||||
return availableBangs.when(
|
||||
data: (availableBangs) {
|
||||
@@ -75,8 +69,8 @@ class BangChips extends HookConsumerWidget {
|
||||
Expanded(
|
||||
child: SelectableChips(
|
||||
itemId: (bang) => bang.trigger,
|
||||
itemAvatar: (bang) =>
|
||||
UrlIcon(bang.getUrl(''), iconSize: 20),
|
||||
itemAvatar:
|
||||
(bang) => UrlIcon(bang.getUrl(''), iconSize: 20),
|
||||
itemLabel: (bang) => Text(bang.websiteName),
|
||||
availableItems: availableBangs,
|
||||
selectedItem: activeBang,
|
||||
@@ -104,9 +98,10 @@ class BangChips extends HookConsumerWidget {
|
||||
|
||||
await context.push(
|
||||
BangSearchRoute(
|
||||
searchText: (searchText?.isEmpty ?? true)
|
||||
? BangSearchRoute.emptySearchText
|
||||
: searchText!,
|
||||
searchText:
|
||||
(searchText?.isEmpty ?? true)
|
||||
? BangSearchRoute.emptySearchText
|
||||
: searchText!,
|
||||
).location,
|
||||
);
|
||||
},
|
||||
@@ -117,10 +112,7 @@ class BangChips extends HookConsumerWidget {
|
||||
);
|
||||
},
|
||||
error: (error, stackTrace) => const SizedBox.shrink(),
|
||||
loading: () => const SizedBox(
|
||||
height: 48,
|
||||
width: double.infinity,
|
||||
),
|
||||
loading: () => const SizedBox(height: 48, width: double.infinity),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,18 +44,15 @@ class SearchField extends HookConsumerWidget {
|
||||
final suggestion = useState<String?>(null);
|
||||
|
||||
if (showSuggestions) {
|
||||
useListenableCallback(
|
||||
textEditingController,
|
||||
() async {
|
||||
if (textEditingController.text.isNotEmpty) {
|
||||
final result = await ref
|
||||
.read(engineSuggestionsProvider.notifier)
|
||||
.getAutocompleteSuggestion(textEditingController.text);
|
||||
useListenableCallback(textEditingController, () async {
|
||||
if (textEditingController.text.isNotEmpty) {
|
||||
final result = await ref
|
||||
.read(engineSuggestionsProvider.notifier)
|
||||
.getAutocompleteSuggestion(textEditingController.text);
|
||||
|
||||
suggestion.value = result;
|
||||
}
|
||||
},
|
||||
);
|
||||
suggestion.value = result;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return AutoSuggestTextField(
|
||||
@@ -66,33 +63,36 @@ class SearchField extends HookConsumerWidget {
|
||||
autofocus: autofocus,
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
prefixIcon: (showBangIcon && activeBang != null)
|
||||
? Padding(
|
||||
padding: const EdgeInsetsDirectional.all(12.0),
|
||||
child: UrlIcon(activeBang!.getUrl(''), iconSize: 24.0),
|
||||
)
|
||||
: null,
|
||||
prefixIcon:
|
||||
(showBangIcon && activeBang != null)
|
||||
? Padding(
|
||||
padding: const EdgeInsetsDirectional.all(12.0),
|
||||
child: UrlIcon(activeBang!.getUrl(''), iconSize: 24.0),
|
||||
)
|
||||
: null,
|
||||
label: label ?? const Text('Search'),
|
||||
// hintText: 'Ask anything...',
|
||||
floatingLabelBehavior: FloatingLabelBehavior.always,
|
||||
suffixIcon: hasText
|
||||
? IconButton(
|
||||
onPressed: () {
|
||||
textEditingController.clear();
|
||||
},
|
||||
icon: const Icon(Icons.clear),
|
||||
)
|
||||
: SpeechToTextButton(
|
||||
onTextReceived: (data) {
|
||||
textEditingController.text = data.toString();
|
||||
},
|
||||
),
|
||||
suffixIcon:
|
||||
hasText
|
||||
? IconButton(
|
||||
onPressed: () {
|
||||
textEditingController.clear();
|
||||
},
|
||||
icon: const Icon(Icons.clear),
|
||||
)
|
||||
: SpeechToTextButton(
|
||||
onTextReceived: (data) {
|
||||
textEditingController.text = data.toString();
|
||||
},
|
||||
),
|
||||
),
|
||||
onTapOutside: (focusNode != null)
|
||||
? (event) {
|
||||
focusNode!.unfocus();
|
||||
}
|
||||
: null,
|
||||
onTapOutside:
|
||||
(focusNode != null)
|
||||
? (event) {
|
||||
focusNode!.unfocus();
|
||||
}
|
||||
: null,
|
||||
onSubmitted: onSubmitted,
|
||||
);
|
||||
}
|
||||
|
||||
+16
-21
@@ -22,14 +22,11 @@ class HistorySuggestions extends HookConsumerWidget {
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final historySuggestions = ref.watch(engineHistorySuggestionsProvider);
|
||||
|
||||
useListenableCallback(
|
||||
searchTextController,
|
||||
() async {
|
||||
await ref
|
||||
.watch(engineSuggestionsProvider.notifier)
|
||||
.addQuery(searchTextController.text);
|
||||
},
|
||||
);
|
||||
useListenableCallback(searchTextController, () async {
|
||||
await ref
|
||||
.watch(engineSuggestionsProvider.notifier)
|
||||
.addQuery(searchTextController.text);
|
||||
});
|
||||
|
||||
if (historySuggestions.hasValue &&
|
||||
(historySuggestions.valueOrNull?.isEmpty ?? true)) {
|
||||
@@ -38,9 +35,7 @@ class HistorySuggestions extends HookConsumerWidget {
|
||||
|
||||
return MultiSliver(
|
||||
children: [
|
||||
const SliverToBoxAdapter(
|
||||
child: Divider(),
|
||||
),
|
||||
const SliverToBoxAdapter(child: Divider()),
|
||||
SliverToBoxAdapter(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 16.0),
|
||||
@@ -76,8 +71,9 @@ class HistorySuggestions extends HookConsumerWidget {
|
||||
width: 24,
|
||||
),
|
||||
),
|
||||
title:
|
||||
suggestion.title.mapNotNull((title) => Text(title)),
|
||||
title: suggestion.title.mapNotNull(
|
||||
(title) => Text(title),
|
||||
),
|
||||
subtitle: suggestion.description.mapNotNull(
|
||||
(description) => Text(
|
||||
description,
|
||||
@@ -117,14 +113,13 @@ class HistorySuggestions extends HookConsumerWidget {
|
||||
exception: error,
|
||||
);
|
||||
},
|
||||
loading: () => SliverList.builder(
|
||||
itemCount: historySuggestions.valueOrNull?.length ?? 3,
|
||||
itemBuilder: (context, index) {
|
||||
return const ListTile(
|
||||
title: Bone.text(),
|
||||
);
|
||||
},
|
||||
),
|
||||
loading:
|
||||
() => SliverList.builder(
|
||||
itemCount: historySuggestions.valueOrNull?.length ?? 3,
|
||||
itemBuilder: (context, index) {
|
||||
return const ListTile(title: Bone.text());
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
+7
-14
@@ -40,14 +40,11 @@ class SearchTermSuggestions extends HookConsumerWidget {
|
||||
|
||||
final searchHistory = ref.watch(searchHistoryProvider);
|
||||
|
||||
useListenableCallback(
|
||||
searchTextController,
|
||||
() async {
|
||||
ref
|
||||
.read(searchSuggestionsProvider().notifier)
|
||||
.addQuery(searchTextController.text);
|
||||
},
|
||||
);
|
||||
useListenableCallback(searchTextController, () async {
|
||||
ref
|
||||
.read(searchSuggestionsProvider().notifier)
|
||||
.addQuery(searchTextController.text);
|
||||
});
|
||||
|
||||
final Widget listSliver;
|
||||
|
||||
@@ -135,9 +132,7 @@ class SearchTermSuggestions extends HookConsumerWidget {
|
||||
if (ref.read(selectedBangTriggerProvider()) ==
|
||||
bang.trigger) {
|
||||
ref
|
||||
.read(
|
||||
selectedBangTriggerProvider().notifier,
|
||||
)
|
||||
.read(selectedBangTriggerProvider().notifier)
|
||||
.clearTrigger();
|
||||
} else {
|
||||
final dialogResult = await BangChips.resetBangDialog(
|
||||
@@ -167,9 +162,7 @@ class SearchTermSuggestions extends HookConsumerWidget {
|
||||
return CustomScrollView(
|
||||
shrinkWrap: true,
|
||||
controller: controller,
|
||||
slivers: [
|
||||
listSliver,
|
||||
],
|
||||
slivers: [listSliver],
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
+58
-62
@@ -32,33 +32,31 @@ class TabSearch extends HookConsumerWidget {
|
||||
),
|
||||
);
|
||||
|
||||
final tabs = ref
|
||||
.watch(
|
||||
seamlessFilteredTabPreviewsProvider(
|
||||
TabSearchPartition.search,
|
||||
(selectedContainer.value != null)
|
||||
? ContainerFilterById(containerId: selectedContainer.value!.id)
|
||||
: ContainerFilterDisabled(),
|
||||
),
|
||||
)
|
||||
.collection;
|
||||
|
||||
useListenableCallback(
|
||||
searchTextController,
|
||||
() async {
|
||||
await ref
|
||||
.read(
|
||||
tabSearchRepositoryProvider(TabSearchPartition.search).notifier,
|
||||
final tabs =
|
||||
ref
|
||||
.watch(
|
||||
seamlessFilteredTabPreviewsProvider(
|
||||
TabSearchPartition.search,
|
||||
(selectedContainer.value != null)
|
||||
? ContainerFilterById(
|
||||
containerId: selectedContainer.value!.id,
|
||||
)
|
||||
: ContainerFilterDisabled(),
|
||||
),
|
||||
)
|
||||
.addQuery(
|
||||
searchTextController.text,
|
||||
// ignore: avoid_redundant_argument_values
|
||||
matchPrefix: _matchPrefix,
|
||||
// ignore: avoid_redundant_argument_values
|
||||
matchSuffix: _matchSuffix,
|
||||
);
|
||||
},
|
||||
);
|
||||
.collection;
|
||||
|
||||
useListenableCallback(searchTextController, () async {
|
||||
await ref
|
||||
.read(tabSearchRepositoryProvider(TabSearchPartition.search).notifier)
|
||||
.addQuery(
|
||||
searchTextController.text,
|
||||
// ignore: avoid_redundant_argument_values
|
||||
matchPrefix: _matchPrefix,
|
||||
// ignore: avoid_redundant_argument_values
|
||||
matchSuffix: _matchSuffix,
|
||||
);
|
||||
});
|
||||
|
||||
return MultiSliver(
|
||||
children: [
|
||||
@@ -68,10 +66,7 @@ class TabSearch extends HookConsumerWidget {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Tabs',
|
||||
style: Theme.of(context).textTheme.labelSmall,
|
||||
),
|
||||
Text('Tabs', style: Theme.of(context).textTheme.labelSmall),
|
||||
ContainerChips(
|
||||
displayMenu: false,
|
||||
selectedContainer: selectedContainer.value,
|
||||
@@ -100,48 +95,49 @@ class TabSearch extends HookConsumerWidget {
|
||||
|
||||
return ListTile(
|
||||
leading: RepaintBoundary(
|
||||
child: (result.icon != null)
|
||||
? RawImage(
|
||||
image: result.icon?.value,
|
||||
height: 24,
|
||||
width: 24,
|
||||
)
|
||||
: UrlIcon(result.url, iconSize: 24),
|
||||
child:
|
||||
(result.icon != null)
|
||||
? RawImage(
|
||||
image: result.icon?.value,
|
||||
height: 24,
|
||||
width: 24,
|
||||
)
|
||||
: UrlIcon(result.url, iconSize: 24),
|
||||
),
|
||||
title: result.title.mapNotNull(
|
||||
(title) => MarkdownBody(
|
||||
data: title,
|
||||
styleSheet: MarkdownStyleSheet(
|
||||
p: Theme.of(context).textTheme.bodyLarge?.copyWith(
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
),
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
subtitle: (bodyHasMatch || urlHasMatch)
|
||||
? MarkdownBody(
|
||||
data: bodyHasMatch
|
||||
? result.content!
|
||||
: result.highlightedUrl!,
|
||||
styleSheet: MarkdownStyleSheet(
|
||||
p: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.onSurfaceVariant,
|
||||
),
|
||||
a: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.onSurfaceVariant,
|
||||
decoration: TextDecoration.none,
|
||||
),
|
||||
subtitle:
|
||||
(bodyHasMatch || urlHasMatch)
|
||||
? MarkdownBody(
|
||||
data:
|
||||
bodyHasMatch
|
||||
? result.content!
|
||||
: result.highlightedUrl!,
|
||||
styleSheet: MarkdownStyleSheet(
|
||||
p: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
color:
|
||||
Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
a: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
color:
|
||||
Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
decoration: TextDecoration.none,
|
||||
),
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
result.url.toString(),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
result.url.toString(),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
onTap: () async {
|
||||
await ref
|
||||
.read(tabRepositoryProvider.notifier)
|
||||
|
||||
Reference in New Issue
Block a user