Toggle navigation
Toggle navigation
This project
Loading...
Sign in
flutter_package
/
fluttertpc_get
Go to a project
Toggle navigation
Projects
Groups
Snippets
Help
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
Jonny Borges
2021-11-27 02:01:04 -0300
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
20d103f7f10cba0015a28abd1354278967233d01
20d103f7
1 parent
4e784a51
add queue, improve logic, close the specific snackbar inside a queue
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
165 additions
and
254 deletions
example/lib/main.dart
lib/get_navigation/get_navigation.dart
lib/get_navigation/src/snackbar/snack.dart → lib/get_navigation/src/snackbar/snackbar.dart
lib/get_navigation/src/snackbar/snackbar_controller.dart
example/lib/main.dart
View file @
20d103f
...
...
@@ -7,7 +7,7 @@ import 'routes/app_pages.dart';
import
'shared/logger/logger_utils.dart'
;
void
main
(
)
{
runApp
(
const
MyApp
());
runApp
(
MyApp
());
}
class
MyApp
extends
StatelessWidget
{
...
...
lib/get_navigation/get_navigation.dart
View file @
20d103f
...
...
@@ -16,5 +16,5 @@ export 'src/routes/get_route.dart';
export
'src/routes/observers/route_observer.dart'
;
export
'src/routes/route_middleware.dart'
;
export
'src/routes/transitions_type.dart'
;
export
'src/snackbar/snack.dart'
;
export
'src/snackbar/snack
bar
.dart'
;
export
'src/snackbar/snackbar_controller.dart'
;
...
...
lib/get_navigation/src/snackbar/snack.dart → lib/get_navigation/src/snackbar/snack
bar
.dart
View file @
20d103f
...
...
@@ -8,6 +8,7 @@ import '../../../get_core/get_core.dart';
import
'../../get_navigation.dart'
;
typedef
OnTap
=
void
Function
(
GetSnackBar
snack
);
typedef
SnackbarStatusCallback
=
void
Function
(
SnackbarStatus
?
status
);
class
GetSnackBar
extends
StatefulWidget
{
...
...
@@ -17,6 +18,11 @@ class GetSnackBar extends StatefulWidget {
/// The title displayed to the user
final
String
?
title
;
/// The direction in which the SnackBar can be dismissed.
///
/// Cannot be null, defaults to [DismissDirection.down] when
/// [snackPosition] == [SnackPosition.BOTTOM] and [DismissDirection.up]
/// when [snackPosition] == [SnackPosition.TOP]
final
DismissDirection
?
dismissDirection
;
/// The message displayed to the user.
...
...
@@ -44,7 +50,8 @@ class GetSnackBar extends StatefulWidget {
/// Check (this example)[https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/material/shadows.dart]
final
List
<
BoxShadow
>?
boxShadows
;
/// Makes [backgroundColor] be ignored.
/// Give to GetSnackbar a gradient background.
/// It Makes [backgroundColor] be ignored.
final
Gradient
?
backgroundGradient
;
/// You can use any widget here, but I recommend [Icon] or [Image] as
...
...
@@ -55,7 +62,10 @@ class GetSnackBar extends StatefulWidget {
/// An option to animate the icon (if present). Defaults to true.
final
bool
shouldIconPulse
;
/// A [TextButton] widget if you need an action from the user.
/// (optional) An action that the user can take based on the snack bar.
///
/// For example, the snack bar might let the user undo the operation that
/// prompted the snackbar.
final
Widget
?
mainButton
;
/// A callback that registers the user's click anywhere.
...
...
@@ -200,6 +210,13 @@ class GetSnackBar extends StatefulWidget {
}
}
enum
RowStyle
{
icon
,
action
,
all
,
none
,
}
/// Indicates Status of snackbar
/// [SnackbarStatus.OPEN] Snack is fully open, [SnackbarStatus.CLOSED] Snackbar
/// has closed,
...
...
@@ -235,12 +252,30 @@ class _GetSnackBarState extends State<GetSnackBar>
final
Completer
<
Size
>
_boxHeightCompleter
=
Completer
<
Size
>();
late
VoidCallback
_progressListener
;
late
CurvedAnimation
_progressAnimation
;
final
_backgroundBoxKey
=
GlobalKey
();
double
get
buttonPadding
{
if
(
widget
.
padding
.
right
-
12
<
0
)
{
return
4
;
}
else
{
return
widget
.
padding
.
right
-
12
;
}
}
RowStyle
get
_rowStyle
{
if
(
widget
.
mainButton
!=
null
&&
widget
.
icon
==
null
)
{
return
RowStyle
.
action
;
}
else
if
(
widget
.
mainButton
==
null
&&
widget
.
icon
!=
null
)
{
return
RowStyle
.
icon
;
}
else
if
(
widget
.
mainButton
!=
null
&&
widget
.
icon
!=
null
)
{
return
RowStyle
.
all
;
}
else
{
return
RowStyle
.
none
;
}
}
@override
Widget
build
(
BuildContext
context
)
{
return
Align
(
...
...
@@ -258,7 +293,42 @@ class _GetSnackBarState extends State<GetSnackBar>
top:
widget
.
snackPosition
==
SnackPosition
.
TOP
,
left:
false
,
right:
false
,
child:
_getSnack
(),
child:
Stack
(
children:
[
FutureBuilder
<
Size
>(
future:
_boxHeightCompleter
.
future
,
builder:
(
context
,
snapshot
)
{
if
(
snapshot
.
hasData
)
{
if
(
widget
.
barBlur
==
0
)
{
return
_emptyWidget
;
}
return
ClipRRect
(
borderRadius:
BorderRadius
.
circular
(
widget
.
borderRadius
),
child:
BackdropFilter
(
filter:
ImageFilter
.
blur
(
sigmaX:
widget
.
barBlur
!,
sigmaY:
widget
.
barBlur
!),
child:
Container
(
height:
snapshot
.
data
!.
height
,
width:
snapshot
.
data
!.
width
,
decoration:
BoxDecoration
(
color:
Colors
.
transparent
,
borderRadius:
BorderRadius
.
circular
(
widget
.
borderRadius
),
),
),
),
);
}
else
{
return
_emptyWidget
;
}
},
),
if
(
widget
.
userInputForm
!=
null
)
_containerWithForm
()
else
_containerWithoutForm
()
],
),
),
),
);
...
...
@@ -267,8 +337,7 @@ class _GetSnackBarState extends State<GetSnackBar>
@override
void
dispose
()
{
_fadeController
?.
dispose
();
widget
.
progressIndicatorController
?.
removeListener
(
_progressListener
);
widget
.
progressIndicatorController
?.
removeListener
(
_updateProgress
);
widget
.
progressIndicatorController
?.
dispose
();
_focusAttachment
.
detach
();
...
...
@@ -284,9 +353,8 @@ class _GetSnackBarState extends State<GetSnackBar>
widget
.
userInputForm
!=
null
||
((
widget
.
message
!=
null
&&
widget
.
message
!.
isNotEmpty
)
||
widget
.
messageText
!=
null
),
"""
A message is mandatory if you are not using userInputForm.
Set either a message or messageText"""
);
'''
You need to either use message[String], or messageText[Widget] or define a userInputForm[Form] in GetSnackbar'''
);
_isTitlePresent
=
(
widget
.
title
!=
null
||
widget
.
titleText
!=
null
);
_messageTopMargin
=
_isTitlePresent
?
6.0
:
widget
.
padding
.
top
;
...
...
@@ -339,10 +407,7 @@ Set either a message or messageText""");
void
_configureProgressIndicatorAnimation
()
{
if
(
widget
.
showProgressIndicator
&&
widget
.
progressIndicatorController
!=
null
)
{
_progressListener
=
()
{
setState
(()
{});
};
widget
.
progressIndicatorController
!.
addListener
(
_progressListener
);
widget
.
progressIndicatorController
!.
addListener
(
_updateProgress
);
_progressAnimation
=
CurvedAnimation
(
curve:
Curves
.
linear
,
parent:
widget
.
progressIndicatorController
!);
...
...
@@ -371,7 +436,7 @@ Set either a message or messageText""");
_fadeController
!.
forward
();
}
Widget
_
generateInputSnack
()
{
Widget
_
containerWithForm
()
{
return
Container
(
key:
_backgroundBoxKey
,
constraints:
widget
.
maxWidth
!=
null
...
...
@@ -383,7 +448,10 @@ Set either a message or messageText""");
boxShadow:
widget
.
boxShadows
,
borderRadius:
BorderRadius
.
circular
(
widget
.
borderRadius
),
border:
widget
.
borderColor
!=
null
?
Border
.
all
(
color:
widget
.
borderColor
!,
width:
widget
.
borderWidth
!)
?
Border
.
all
(
color:
widget
.
borderColor
!,
width:
widget
.
borderWidth
!,
)
:
null
,
),
child:
Padding
(
...
...
@@ -398,7 +466,14 @@ Set either a message or messageText""");
);
}
Widget
_generateSnack
()
{
Widget
_containerWithoutForm
()
{
final
iconPadding
=
widget
.
padding
.
left
>
16.0
?
widget
.
padding
.
left
:
0.0
;
final
left
=
_rowStyle
==
RowStyle
.
icon
||
_rowStyle
==
RowStyle
.
all
?
4.0
:
widget
.
padding
.
left
;
final
right
=
_rowStyle
==
RowStyle
.
action
||
_rowStyle
==
RowStyle
.
all
?
8.0
:
widget
.
padding
.
right
;
return
Container
(
key:
_backgroundBoxKey
,
constraints:
widget
.
maxWidth
!=
null
...
...
@@ -427,177 +502,65 @@ Set either a message or messageText""");
:
_emptyWidget
,
Row
(
mainAxisSize:
MainAxisSize
.
max
,
children:
_getAppropriateRowLayout
(),
),
],
),
);
}
List
<
Widget
>
_getAppropriateRowLayout
()
{
double
buttonRightPadding
;
var
iconPadding
=
0.0
;
if
(
widget
.
padding
.
right
-
12
<
0
)
{
buttonRightPadding
=
4
;
}
else
{
buttonRightPadding
=
widget
.
padding
.
right
-
12
;
}
if
(
widget
.
padding
.
left
>
16.0
)
{
iconPadding
=
widget
.
padding
.
left
;
}
if
(
widget
.
icon
==
null
&&
widget
.
mainButton
==
null
)
{
return
[
_buildLeftBarIndicator
(),
Expanded
(
flex:
1
,
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
stretch
,
mainAxisSize:
MainAxisSize
.
min
,
children:
<
Widget
>[
(
_isTitlePresent
)
?
Padding
(
padding:
EdgeInsets
.
only
(
top:
widget
.
padding
.
top
,
left:
widget
.
padding
.
left
,
right:
widget
.
padding
.
right
,
),
child:
_getTitleText
(),
)
:
_emptyWidget
,
Padding
(
padding:
EdgeInsets
.
only
(
top:
_messageTopMargin
,
left:
widget
.
padding
.
left
,
right:
widget
.
padding
.
right
,
bottom:
widget
.
padding
.
bottom
,
children:
[
_buildLeftBarIndicator
(),
if
(
_rowStyle
==
RowStyle
.
icon
)
ConstrainedBox
(
constraints:
BoxConstraints
.
tightFor
(
width:
42.0
+
iconPadding
),
child:
_getIcon
(),
),
child:
widget
.
messageText
??
_getDefaultNotificationText
(),
),
],
),
),
];
}
else
if
(
widget
.
icon
!=
null
&&
widget
.
mainButton
==
null
)
{
return
<
Widget
>[
_buildLeftBarIndicator
(),
ConstrainedBox
(
constraints:
BoxConstraints
.
tightFor
(
width:
42.0
+
iconPadding
),
child:
_getIcon
(),
),
Expanded
(
flex:
1
,
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
stretch
,
mainAxisSize:
MainAxisSize
.
min
,
children:
<
Widget
>[
(
_isTitlePresent
)
?
Padding
(
Expanded
(
flex:
1
,
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
stretch
,
mainAxisSize:
MainAxisSize
.
min
,
children:
<
Widget
>[
if
(
_isTitlePresent
)
Padding
(
padding:
EdgeInsets
.
only
(
top:
widget
.
padding
.
top
,
left:
left
,
right:
right
,
),
child:
widget
.
titleText
??
Text
(
widget
.
title
??
""
,
style:
TextStyle
(
fontSize:
16.0
,
color:
Colors
.
white
,
fontWeight:
FontWeight
.
bold
,
),
),
)
else
_emptyWidget
,
Padding
(
padding:
EdgeInsets
.
only
(
top:
widget
.
padding
.
top
,
left:
4.0
,
right:
widget
.
padding
.
left
,
top:
_messageTopMargin
,
left:
left
,
right:
right
,
bottom:
widget
.
padding
.
bottom
,
),
child:
_getTitleText
(),
)
:
_emptyWidget
,
Padding
(
padding:
EdgeInsets
.
only
(
top:
_messageTopMargin
,
left:
4.0
,
right:
widget
.
padding
.
right
,
bottom:
widget
.
padding
.
bottom
,
child:
widget
.
messageText
??
Text
(
widget
.
message
??
""
,
style:
TextStyle
(
fontSize:
14.0
,
color:
Colors
.
white
),
),
),
],
),
child:
widget
.
messageText
??
_getDefaultNotificationText
(),
),
],
),
),
];
}
else
if
(
widget
.
icon
==
null
&&
widget
.
mainButton
!=
null
)
{
return
<
Widget
>[
_buildLeftBarIndicator
(),
Expanded
(
flex:
1
,
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
stretch
,
mainAxisSize:
MainAxisSize
.
min
,
children:
<
Widget
>[
(
_isTitlePresent
)
?
Padding
(
padding:
EdgeInsets
.
only
(
top:
widget
.
padding
.
top
,
left:
widget
.
padding
.
left
,
right:
widget
.
padding
.
right
,
),
child:
_getTitleText
(),
)
:
_emptyWidget
,
Padding
(
padding:
EdgeInsets
.
only
(
top:
_messageTopMargin
,
left:
widget
.
padding
.
left
,
right:
8.0
,
bottom:
widget
.
padding
.
bottom
,
if
(
_rowStyle
==
RowStyle
.
action
)
Padding
(
padding:
EdgeInsets
.
only
(
right:
buttonPadding
),
child:
widget
.
mainButton
,
),
child:
widget
.
messageText
??
_getDefaultNotificationText
(),
),
],
),
),
Padding
(
padding:
EdgeInsets
.
only
(
right:
buttonRightPadding
),
child:
_getMainActionButton
(),
),
];
}
else
{
return
<
Widget
>[
_buildLeftBarIndicator
(),
ConstrainedBox
(
constraints:
BoxConstraints
.
tightFor
(
width:
42.0
+
iconPadding
),
child:
_getIcon
(),
),
Expanded
(
flex:
1
,
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
stretch
,
mainAxisSize:
MainAxisSize
.
min
,
children:
<
Widget
>[
(
_isTitlePresent
)
?
Padding
(
padding:
EdgeInsets
.
only
(
top:
widget
.
padding
.
top
,
left:
4.0
,
right:
8.0
,
),
child:
_getTitleText
(),
)
:
_emptyWidget
,
Padding
(
padding:
EdgeInsets
.
only
(
top:
_messageTopMargin
,
left:
4.0
,
right:
8.0
,
bottom:
widget
.
padding
.
bottom
,
),
child:
widget
.
messageText
??
_getDefaultNotificationText
(),
),
],
),
),
Padding
(
padding:
EdgeInsets
.
only
(
right:
buttonRightPadding
),
child:
_getMainActionButton
(),
),
];
}
}
Text
_getDefaultNotificationText
()
{
return
Text
(
widget
.
message
??
""
,
style:
TextStyle
(
fontSize:
14.0
,
color:
Colors
.
white
),
],
),
);
}
...
...
@@ -614,59 +577,5 @@ Set either a message or messageText""");
}
}
Widget
?
_getMainActionButton
()
{
return
widget
.
mainButton
;
}
Widget
_getSnack
()
{
Widget
snack
;
if
(
widget
.
userInputForm
!=
null
)
{
snack
=
_generateInputSnack
();
}
else
{
snack
=
_generateSnack
();
}
return
Stack
(
children:
[
FutureBuilder
<
Size
>(
future:
_boxHeightCompleter
.
future
,
builder:
(
context
,
snapshot
)
{
if
(
snapshot
.
hasData
)
{
if
(
widget
.
barBlur
==
0
)
{
return
_emptyWidget
;
}
return
ClipRRect
(
borderRadius:
BorderRadius
.
circular
(
widget
.
borderRadius
),
child:
BackdropFilter
(
filter:
ImageFilter
.
blur
(
sigmaX:
widget
.
barBlur
!,
sigmaY:
widget
.
barBlur
!),
child:
Container
(
height:
snapshot
.
data
!.
height
,
width:
snapshot
.
data
!.
width
,
decoration:
BoxDecoration
(
color:
Colors
.
transparent
,
borderRadius:
BorderRadius
.
circular
(
widget
.
borderRadius
),
),
),
),
);
}
else
{
return
_emptyWidget
;
}
},
),
snack
,
],
);
}
Widget
_getTitleText
()
{
return
widget
.
titleText
??
Text
(
widget
.
title
??
""
,
style:
TextStyle
(
fontSize:
16.0
,
color:
Colors
.
white
,
fontWeight:
FontWeight
.
bold
),
);
}
void
_updateProgress
()
=>
setState
(()
{});
}
...
...
lib/get_navigation/src/snackbar/snackbar_controller.dart
View file @
20d103f
...
...
@@ -7,7 +7,7 @@ import '../../../get.dart';
class
SnackbarController
{
static
final
_snackBarQueue
=
_SnackBarQueue
();
static
bool
get
isSnackbarBeingShown
=>
_snackBarQueue
.
isJobInProgress
;
static
bool
get
isSnackbarBeingShown
=>
_snackBarQueue
.
_
isJobInProgress
;
late
Animation
<
double
>
_filterBlurAnimation
;
late
Animation
<
Color
?>
_filterColorAnimation
;
...
...
@@ -54,7 +54,7 @@ class SnackbarController {
/// Only one GetSnackbar will be displayed at a time, and this method returns
/// a future to when the snackbar disappears.
Future
<
void
>
show
()
{
return
_snackBarQueue
.
addJob
(
this
);
return
_snackBarQueue
.
_
addJob
(
this
);
}
void
_cancelTimer
()
{
...
...
@@ -319,7 +319,8 @@ class SnackbarController {
element
.
remove
();
}
assert
(!
_transitionCompleter
.
isCompleted
,
'Cannot remove overlay twice.'
);
assert
(!
_transitionCompleter
.
isCompleted
,
'Cannot remove overlay from a disposed snackbar'
);
_controller
.
dispose
();
_overlayEntries
.
clear
();
_transitionCompleter
.
complete
(
this
);
...
...
@@ -331,38 +332,39 @@ class SnackbarController {
}
static
void
cancelAllSnackbars
()
{
_snackBarQueue
.
cancelAllJobs
();
_snackBarQueue
.
_
cancelAllJobs
();
}
static
Future
<
void
>
closeCurrentSnackbar
()
async
{
await
_snackBarQueue
.
closeCurrentJob
();
await
_snackBarQueue
.
_
closeCurrentJob
();
}
}
class
_SnackBarQueue
{
final
_queue
=
GetQueue
();
final
_snackbarList
=
<
SnackbarController
>[];
bool
_isJobInProgress
=
false
;
SnackbarController
?
_currentSnackbar
;
SnackbarController
?
get
_currentSnackbar
{
if
(
_snackbarList
.
isEmpty
)
return
null
;
return
_snackbarList
.
first
;
}
bool
get
isJobInProgress
=>
_isJobInProgress
;
bool
get
_isJobInProgress
=>
_snackbarList
.
isNotEmpty
;
Future
<
void
>
addJob
(
SnackbarController
job
)
async
{
_isJobInProgress
=
true
;
_currentSnackbar
=
job
;
Future
<
void
>
_addJob
(
SnackbarController
job
)
async
{
_snackbarList
.
add
(
job
);
final
data
=
await
_queue
.
add
(
job
.
_show
);
_isJobInProgress
=
false
;
_currentSnackbar
=
null
;
_snackbarList
.
remove
(
job
);
return
data
;
}
void
cancelAllJobs
()
{
_currentSnackbar
?.
close
();
Future
<
void
>
_cancelAllJobs
()
async
{
await
_currentSnackbar
?.
close
();
_queue
.
cancelAllJobs
();
_snackbarList
.
clear
();
}
Future
<
void
>
closeCurrentJob
()
async
{
Future
<
void
>
_
closeCurrentJob
()
async
{
await
_currentSnackbar
?.
close
();
}
}
...
...
Please
register
or
login
to post a comment