Working on message search+filter
This commit is contained in:
parent
e9ea573e33
commit
0bbe5fc7fa
@ -1,14 +1,18 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:simplecloudnotifier/components/layout/app_bar_filter_dialog.dart';
|
||||
import 'package:simplecloudnotifier/components/layout/app_bar_progress_indicator.dart';
|
||||
import 'package:simplecloudnotifier/pages/debug/debug_main.dart';
|
||||
import 'package:simplecloudnotifier/settings/app_settings.dart';
|
||||
import 'package:simplecloudnotifier/state/app_bar_state.dart';
|
||||
import 'package:simplecloudnotifier/state/app_theme.dart';
|
||||
import 'package:simplecloudnotifier/utils/navi.dart';
|
||||
import 'package:simplecloudnotifier/utils/toaster.dart';
|
||||
|
||||
class SCNAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
const SCNAppBar({
|
||||
class SCNAppBar extends StatefulWidget implements PreferredSizeWidget {
|
||||
SCNAppBar({
|
||||
Key? key,
|
||||
required this.title,
|
||||
required this.showThemeSwitch,
|
||||
@ -23,6 +27,22 @@ class SCNAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
final bool showShare;
|
||||
final void Function()? onShare;
|
||||
|
||||
@override
|
||||
Size get preferredSize => const Size.fromHeight(kToolbarHeight);
|
||||
|
||||
@override
|
||||
State<SCNAppBar> createState() => _SCNAppBarState();
|
||||
}
|
||||
|
||||
class _SCNAppBarState extends State<SCNAppBar> {
|
||||
final TextEditingController _ctrlSearchField = TextEditingController();
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_ctrlSearchField.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final cfg = Provider.of<AppSettings>(context);
|
||||
@ -39,7 +59,7 @@ class SCNAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
));
|
||||
}
|
||||
|
||||
if (showThemeSwitch) {
|
||||
if (widget.showThemeSwitch) {
|
||||
actions.add(Consumer<AppTheme>(
|
||||
builder: (context, appTheme, child) => IconButton(
|
||||
icon: Icon(appTheme.darkMode ? FontAwesomeIcons.solidSun : FontAwesomeIcons.solidMoon),
|
||||
@ -48,54 +68,117 @@ class SCNAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
),
|
||||
));
|
||||
} else {
|
||||
actions.add(Visibility(
|
||||
visible: false,
|
||||
maintainSize: true,
|
||||
maintainAnimation: true,
|
||||
maintainState: true,
|
||||
child: IconButton(
|
||||
icon: const Icon(FontAwesomeIcons.square),
|
||||
onPressed: () {/*TODO*/},
|
||||
),
|
||||
));
|
||||
actions.add(_buildSpacer());
|
||||
}
|
||||
|
||||
if (showSearch) {
|
||||
if (widget.showSearch) {
|
||||
actions.add(IconButton(
|
||||
icon: const Icon(FontAwesomeIcons.solidFilter),
|
||||
tooltip: 'Filter',
|
||||
onPressed: () => _showFilterDialog(context),
|
||||
));
|
||||
actions.add(IconButton(
|
||||
icon: const Icon(FontAwesomeIcons.solidMagnifyingGlass),
|
||||
tooltip: 'Search',
|
||||
onPressed: () {/*TODO*/},
|
||||
onPressed: () => AppBarState().setShowSearchField(true),
|
||||
));
|
||||
} else if (showShare) {
|
||||
} else if (widget.showShare) {
|
||||
actions.add(_buildSpacer());
|
||||
actions.add(IconButton(
|
||||
icon: const Icon(FontAwesomeIcons.solidShareNodes),
|
||||
tooltip: 'Share',
|
||||
onPressed: onShare ?? () {},
|
||||
onPressed: widget.onShare ?? () {},
|
||||
));
|
||||
} else {
|
||||
actions.add(Visibility(
|
||||
visible: false,
|
||||
maintainSize: true,
|
||||
maintainAnimation: true,
|
||||
maintainState: true,
|
||||
child: IconButton(
|
||||
icon: const Icon(FontAwesomeIcons.square),
|
||||
onPressed: () {/*TODO*/},
|
||||
),
|
||||
));
|
||||
actions.add(_buildSpacer());
|
||||
}
|
||||
|
||||
return AppBar(
|
||||
title: Text(title ?? 'Simple Cloud Notifier 2.0'),
|
||||
actions: actions,
|
||||
backgroundColor: Theme.of(context).secondaryHeaderColor,
|
||||
bottom: PreferredSize(
|
||||
preferredSize: Size(double.infinity, 1.0),
|
||||
child: AppBarProgressIndicator(),
|
||||
return Consumer<AppBarState>(builder: (context, value, child) {
|
||||
if (value.showSearchField) {
|
||||
return AppBar(
|
||||
leading: IconButton(
|
||||
icon: const Icon(FontAwesomeIcons.solidArrowLeft),
|
||||
onPressed: () {
|
||||
value.setShowSearchField(false);
|
||||
},
|
||||
),
|
||||
title: _buildSearchTextField(context),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(FontAwesomeIcons.solidMagnifyingGlass),
|
||||
onPressed: () {
|
||||
value.setShowSearchField(false);
|
||||
AppBarState().notifySearchListeners(_ctrlSearchField.text);
|
||||
_ctrlSearchField.clear();
|
||||
},
|
||||
),
|
||||
],
|
||||
backgroundColor: Theme.of(context).secondaryHeaderColor,
|
||||
bottom: PreferredSize(
|
||||
preferredSize: Size(double.infinity, 1.0),
|
||||
child: AppBarProgressIndicator(show: value.loadingIndeterminate),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return AppBar(
|
||||
title: Text(widget.title ?? 'SCN'),
|
||||
actions: actions,
|
||||
backgroundColor: Theme.of(context).secondaryHeaderColor,
|
||||
bottom: PreferredSize(
|
||||
preferredSize: Size(double.infinity, 1.0),
|
||||
child: AppBarProgressIndicator(show: value.loadingIndeterminate),
|
||||
),
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Visibility _buildSpacer() {
|
||||
return Visibility(
|
||||
visible: false,
|
||||
maintainSize: true,
|
||||
maintainAnimation: true,
|
||||
maintainState: true,
|
||||
child: IconButton(
|
||||
icon: const Icon(FontAwesomeIcons.square),
|
||||
onPressed: () {/* NO-OP */},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Size get preferredSize => const Size.fromHeight(kToolbarHeight);
|
||||
Widget _buildSearchTextField(BuildContext context) {
|
||||
return TextField(
|
||||
controller: _ctrlSearchField,
|
||||
autofocus: true,
|
||||
style: TextStyle(fontSize: 20),
|
||||
textInputAction: TextInputAction.search,
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Search',
|
||||
),
|
||||
onSubmitted: (value) {
|
||||
AppBarState().setShowSearchField(false);
|
||||
AppBarState().notifySearchListeners(_ctrlSearchField.text);
|
||||
_ctrlSearchField.clear();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _showFilterDialog(BuildContext context) {
|
||||
double vpWidth = MediaQuery.sizeOf(context).width;
|
||||
|
||||
showDialog<void>(
|
||||
context: context,
|
||||
barrierDismissible: true,
|
||||
barrierColor: Colors.transparent,
|
||||
builder: (BuildContext context) {
|
||||
return Dialog(
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(0)),
|
||||
alignment: Alignment.topCenter,
|
||||
insetPadding: EdgeInsets.fromLTRB(0, this.widget.preferredSize.height, 0, 0),
|
||||
backgroundColor: Colors.transparent,
|
||||
child: AppBarFilterDialog(),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
86
flutter/lib/components/layout/app_bar_filter_dialog.dart
Normal file
86
flutter/lib/components/layout/app_bar_filter_dialog.dart
Normal file
@ -0,0 +1,86 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:simplecloudnotifier/utils/navi.dart';
|
||||
|
||||
class AppBarFilterDialog extends StatefulWidget {
|
||||
@override
|
||||
_AppBarFilterDialogState createState() => _AppBarFilterDialogState();
|
||||
}
|
||||
|
||||
class _AppBarFilterDialogState extends State<AppBarFilterDialog> {
|
||||
double _height = 0;
|
||||
|
||||
double _targetHeight = 4 + (48 * 6) + (16 * 5) + 4;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
Future.delayed(Duration.zero, () {
|
||||
setState(() {
|
||||
_height = _targetHeight;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
double vpWidth = MediaQuery.sizeOf(context).width;
|
||||
|
||||
return Container(
|
||||
margin: const EdgeInsets.all(0),
|
||||
width: vpWidth,
|
||||
color: Colors.transparent,
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
color: Theme.of(context).secondaryHeaderColor,
|
||||
child: AnimatedContainer(
|
||||
duration: Duration(milliseconds: 350),
|
||||
curve: Curves.easeInCubic,
|
||||
height: _height,
|
||||
child: ClipRect(
|
||||
child: OverflowBox(
|
||||
alignment: Alignment.topCenter,
|
||||
maxWidth: vpWidth,
|
||||
minWidth: vpWidth,
|
||||
minHeight: 0,
|
||||
maxHeight: _targetHeight,
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(height: 4),
|
||||
_buildFilterItem(context, FontAwesomeIcons.magnifyingGlass, 'Search'),
|
||||
Divider(),
|
||||
_buildFilterItem(context, FontAwesomeIcons.snake, 'Channel'),
|
||||
Divider(),
|
||||
_buildFilterItem(context, FontAwesomeIcons.signature, 'Sender'),
|
||||
Divider(),
|
||||
_buildFilterItem(context, FontAwesomeIcons.timer, 'Time'),
|
||||
Divider(),
|
||||
_buildFilterItem(context, FontAwesomeIcons.bolt, 'Priority'),
|
||||
Divider(),
|
||||
_buildFilterItem(context, FontAwesomeIcons.gearCode, 'Key'),
|
||||
SizedBox(height: 4),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(child: GestureDetector(child: Container(width: vpWidth, color: Color(0x88000000)), onTap: () => Navi.popDialog(context))),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildFilterItem(BuildContext context, IconData icon, String label) {
|
||||
return ListTile(
|
||||
visualDensity: VisualDensity.compact,
|
||||
title: Text(label),
|
||||
leading: Icon(icon),
|
||||
onTap: () {
|
||||
Navi.popDialog(context);
|
||||
//TOOD show more...
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
@ -1,21 +1,19 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:simplecloudnotifier/state/app_bar_state.dart';
|
||||
|
||||
class AppBarProgressIndicator extends StatelessWidget implements PreferredSizeWidget {
|
||||
AppBarProgressIndicator({required this.show});
|
||||
|
||||
final bool show;
|
||||
|
||||
@override
|
||||
Size get preferredSize => Size(double.infinity, 1.0);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Consumer<AppBarState>(
|
||||
builder: (context, value, child) {
|
||||
if (value.loadingIndeterminate) {
|
||||
return LinearProgressIndicator(value: null);
|
||||
} else {
|
||||
return SizedBox.square(dimension: 4); // 4 height is the same as the LinearProgressIndicator
|
||||
}
|
||||
},
|
||||
);
|
||||
if (show) {
|
||||
return LinearProgressIndicator(value: null);
|
||||
} else {
|
||||
return SizedBox.square(dimension: 4); // 4 height is the same as the LinearProgressIndicator
|
||||
}
|
||||
}
|
||||
}
|
||||
|
36
flutter/lib/pages/message_list/message_filter_chiplet.dart
Normal file
36
flutter/lib/pages/message_list/message_filter_chiplet.dart
Normal file
@ -0,0 +1,36 @@
|
||||
import 'package:flutter/src/widgets/icon_data.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
|
||||
enum MessageFilterChipletType {
|
||||
search,
|
||||
channel,
|
||||
sender,
|
||||
timeRange,
|
||||
priority,
|
||||
sendkey,
|
||||
}
|
||||
|
||||
class MessageFilterChiplet {
|
||||
final String label;
|
||||
final String value;
|
||||
final MessageFilterChipletType type;
|
||||
|
||||
MessageFilterChiplet({required this.label, required this.value, required this.type});
|
||||
|
||||
IconData? icon() {
|
||||
switch (type) {
|
||||
case MessageFilterChipletType.search:
|
||||
return FontAwesomeIcons.magnifyingGlass;
|
||||
case MessageFilterChipletType.channel:
|
||||
return FontAwesomeIcons.snake;
|
||||
case MessageFilterChipletType.sender:
|
||||
return FontAwesomeIcons.signature;
|
||||
case MessageFilterChipletType.timeRange:
|
||||
return FontAwesomeIcons.timer;
|
||||
case MessageFilterChipletType.priority:
|
||||
return FontAwesomeIcons.bolt;
|
||||
case MessageFilterChipletType.sendkey:
|
||||
return FontAwesomeIcons.gearCode;
|
||||
}
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ import 'package:provider/provider.dart';
|
||||
import 'package:simplecloudnotifier/api/api_client.dart';
|
||||
import 'package:simplecloudnotifier/models/channel.dart';
|
||||
import 'package:simplecloudnotifier/models/scn_message.dart';
|
||||
import 'package:simplecloudnotifier/pages/message_list/message_filter_chiplet.dart';
|
||||
import 'package:simplecloudnotifier/pages/message_view/message_view.dart';
|
||||
import 'package:simplecloudnotifier/settings/app_settings.dart';
|
||||
import 'package:simplecloudnotifier/state/app_bar_state.dart';
|
||||
@ -34,10 +35,14 @@ class _MessageListPageState extends State<MessageListPage> with RouteAware {
|
||||
|
||||
bool _isInitialized = false;
|
||||
|
||||
List<MessageFilterChiplet> _filterChiplets = [];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
AppBarState().subscribeSearchListener(_onAppBarSearch);
|
||||
|
||||
_pagingController.addPageRequestListener(_fetchPage);
|
||||
|
||||
if (widget.isVisiblePage && !_isInitialized) _realInitState();
|
||||
@ -94,6 +99,7 @@ class _MessageListPageState extends State<MessageListPage> with RouteAware {
|
||||
@override
|
||||
void dispose() {
|
||||
ApplicationLog.debug('MessageListPage::dispose');
|
||||
AppBarState().unsubscribeSearchListener(_onAppBarSearch);
|
||||
Navi.modalRouteObserver.unsubscribe(this);
|
||||
_pagingController.dispose();
|
||||
_lifecyleListener.dispose();
|
||||
@ -222,22 +228,50 @@ class _MessageListPageState extends State<MessageListPage> with RouteAware {
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.fromLTRB(8, 4, 8, 4),
|
||||
child: RefreshIndicator(
|
||||
onRefresh: () => Future.sync(
|
||||
() => _pagingController.refresh(),
|
||||
),
|
||||
child: PagedListView<String, SCNMessage>(
|
||||
pagingController: _pagingController,
|
||||
builderDelegate: PagedChildBuilderDelegate<SCNMessage>(
|
||||
itemBuilder: (context, item, index) => MessageListItem(
|
||||
message: item,
|
||||
allChannels: _channels ?? {},
|
||||
onPressed: () {
|
||||
Navi.push(context, () => MessageViewPage(message: item));
|
||||
},
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
if (_filterChiplets.isNotEmpty)
|
||||
Wrap(
|
||||
alignment: WrapAlignment.start,
|
||||
spacing: 5.0,
|
||||
children: [
|
||||
for (var chiplet in _filterChiplets) _buildFilterChip(context, chiplet),
|
||||
],
|
||||
),
|
||||
Expanded(
|
||||
child: RefreshIndicator(
|
||||
onRefresh: () => Future.sync(
|
||||
() => _pagingController.refresh(),
|
||||
),
|
||||
child: PagedListView<String, SCNMessage>(
|
||||
pagingController: _pagingController,
|
||||
builderDelegate: PagedChildBuilderDelegate<SCNMessage>(
|
||||
itemBuilder: (context, item, index) => MessageListItem(
|
||||
message: item,
|
||||
allChannels: _channels ?? {},
|
||||
onPressed: () {
|
||||
Navi.push(context, () => MessageViewPage(message: item));
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildFilterChip(BuildContext context, MessageFilterChiplet chiplet) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.fromLTRB(0, 2, 0, 2),
|
||||
child: InputChip(
|
||||
avatar: Icon(chiplet.icon()),
|
||||
label: Text(chiplet.label),
|
||||
onDeleted: () => setState(() => _filterChiplets.remove(chiplet)),
|
||||
onPressed: () {/* TODO idk what to do here ? */},
|
||||
visualDensity: VisualDensity(horizontal: -4, vertical: -4),
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -269,4 +303,10 @@ class _MessageListPageState extends State<MessageListPage> with RouteAware {
|
||||
await cache.delete(val.messageID);
|
||||
}
|
||||
}
|
||||
|
||||
void _onAppBarSearch(String str) {
|
||||
setState(() {
|
||||
_filterChiplets = _filterChiplets.where((element) => false).toList() + [MessageFilterChiplet(label: str, value: str, type: MessageFilterChipletType.search)];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -137,6 +137,7 @@ class _MessageViewPageState extends State<MessageViewPage> {
|
||||
_buildMetaCard(context, FontAwesomeIcons.solidSnake, 'Channel', [message.channelID, channel?.displayName ?? message.channelInternalName], () => {/*TODO*/}),
|
||||
_buildMetaCard(context, FontAwesomeIcons.solidTimer, 'Timestamp', [message.timestamp], null),
|
||||
_buildMetaCard(context, FontAwesomeIcons.solidUser, 'User', [if (user != null) user.userID, if (user?.username != null) user!.username!], () => {/*TODO*/}), //TODO
|
||||
_buildMetaCard(context, FontAwesomeIcons.solidBolt, 'Priority', [_prettyPrintPriority(message.priority)], () => {/*TODO*/}), //TODO
|
||||
if (message.senderUserID == userAccUserID) UI.button(text: "Delete Message", onPressed: () {/*TODO*/}, color: Colors.red[900]),
|
||||
],
|
||||
),
|
||||
@ -252,4 +253,17 @@ class _MessageViewPageState extends State<MessageViewPage> {
|
||||
String _preformatTitle(SCNMessage message) {
|
||||
return message.title.replaceAll('\n', '').replaceAll('\r', '').replaceAll('\t', ' ');
|
||||
}
|
||||
|
||||
String _prettyPrintPriority(int priority) {
|
||||
switch (priority) {
|
||||
case 0:
|
||||
return 'Low (0)';
|
||||
case 1:
|
||||
return 'Normal (1)';
|
||||
case 2:
|
||||
return 'High (2)';
|
||||
default:
|
||||
return 'Unknown ($priority)';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,12 +9,37 @@ class AppBarState extends ChangeNotifier {
|
||||
|
||||
AppBarState._internal() {}
|
||||
|
||||
List<void Function(String)> _searchListeners = [];
|
||||
|
||||
bool _loadingIndeterminate = false;
|
||||
bool get loadingIndeterminate => _loadingIndeterminate;
|
||||
|
||||
bool _showSearchField = false;
|
||||
bool get showSearchField => _showSearchField;
|
||||
|
||||
void setLoadingIndeterminate(bool v) {
|
||||
if (_loadingIndeterminate == v) return;
|
||||
_loadingIndeterminate = v;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setShowSearchField(bool v) {
|
||||
if (_showSearchField == v) return;
|
||||
_showSearchField = v;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void subscribeSearchListener(void Function(String) listener) {
|
||||
_searchListeners.add(listener);
|
||||
}
|
||||
|
||||
void unsubscribeSearchListener(void Function(String) listener) {
|
||||
_searchListeners.remove(listener);
|
||||
}
|
||||
|
||||
void notifySearchListeners(String query) {
|
||||
for (var listener in _searchListeners) {
|
||||
listener(query);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -158,11 +158,11 @@ class FBMessage extends HiveObject implements FieldDebuggable {
|
||||
this.notificationAndroidCount = rmsg.notification?.android?.count,
|
||||
this.notificationAndroidImageUrl = rmsg.notification?.android?.imageUrl,
|
||||
this.notificationAndroidLink = rmsg.notification?.android?.link,
|
||||
this.notificationAndroidPriority = rmsg.notification?.android?.priority?.toString(),
|
||||
this.notificationAndroidPriority = rmsg.notification?.android?.priority.toString(),
|
||||
this.notificationAndroidSmallIcon = rmsg.notification?.android?.smallIcon,
|
||||
this.notificationAndroidSound = rmsg.notification?.android?.sound,
|
||||
this.notificationAndroidTicker = rmsg.notification?.android?.ticker,
|
||||
this.notificationAndroidVisibility = rmsg.notification?.android?.visibility?.toString(),
|
||||
this.notificationAndroidVisibility = rmsg.notification?.android?.visibility.toString(),
|
||||
this.notificationAndroidTag = rmsg.notification?.android?.tag,
|
||||
this.notificationAppleBadge = rmsg.notification?.apple?.badge,
|
||||
this.notificationAppleSound = rmsg.notification?.apple?.sound?.toString(),
|
||||
|
@ -1,4 +1,3 @@
|
||||
import 'dart:ffi';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:device_info_plus/device_info_plus.dart';
|
||||
|
@ -8,15 +8,21 @@ class Navi {
|
||||
|
||||
static void push<T extends Widget>(BuildContext context, T Function() builder) {
|
||||
Provider.of<AppBarState>(context, listen: false).setLoadingIndeterminate(false);
|
||||
Provider.of<AppBarState>(context, listen: false).setShowSearchField(false);
|
||||
|
||||
Navigator.push(context, MaterialPageRoute<T>(builder: (context) => builder()));
|
||||
}
|
||||
|
||||
static void popToRoot(BuildContext context) {
|
||||
Provider.of<AppBarState>(context, listen: false).setLoadingIndeterminate(false);
|
||||
Provider.of<AppBarState>(context, listen: false).setShowSearchField(false);
|
||||
|
||||
Navigator.popUntil(context, (route) => route.isFirst);
|
||||
}
|
||||
|
||||
static void popDialog(BuildContext dialogContext) {
|
||||
Navigator.pop(dialogContext);
|
||||
}
|
||||
}
|
||||
|
||||
class SCNRouteObserver extends RouteObserver<PageRoute<dynamic>> {
|
||||
@ -25,6 +31,7 @@ class SCNRouteObserver extends RouteObserver<PageRoute<dynamic>> {
|
||||
super.didPush(route, previousRoute);
|
||||
if (route is PageRoute) {
|
||||
AppBarState().setLoadingIndeterminate(false);
|
||||
AppBarState().setShowSearchField(false);
|
||||
|
||||
print('[SCNRouteObserver] .didPush()');
|
||||
}
|
||||
@ -35,6 +42,7 @@ class SCNRouteObserver extends RouteObserver<PageRoute<dynamic>> {
|
||||
super.didReplace(newRoute: newRoute, oldRoute: oldRoute);
|
||||
if (newRoute is PageRoute) {
|
||||
AppBarState().setLoadingIndeterminate(false);
|
||||
AppBarState().setShowSearchField(false);
|
||||
|
||||
print('[SCNRouteObserver] .didReplace()');
|
||||
}
|
||||
@ -45,6 +53,7 @@ class SCNRouteObserver extends RouteObserver<PageRoute<dynamic>> {
|
||||
super.didPop(route, previousRoute);
|
||||
if (previousRoute is PageRoute && route is PageRoute) {
|
||||
AppBarState().setLoadingIndeterminate(false);
|
||||
AppBarState().setShowSearchField(false);
|
||||
|
||||
print('[SCNRouteObserver] .didPop()');
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user