mirror of
				https://gitlab.com/comunic/comunicmobile
				synced 2025-10-31 02:04:52 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			174 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
			
		
		
	
	
			174 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
| import 'package:cached_network_image/cached_network_image.dart';
 | |
| import 'package:comunic/utils/intl_utils.dart';
 | |
| import 'package:flutter/material.dart';
 | |
| 
 | |
| /// User interface utilities
 | |
| ///
 | |
| /// @author Pierre HUBERT
 | |
| 
 | |
| /// Build centered progress bar
 | |
| Widget buildCenteredProgressBar() {
 | |
|   return Center(
 | |
|     child: CircularProgressIndicator(),
 | |
|   );
 | |
| }
 | |
| 
 | |
| /// Build and return a full loading page
 | |
| Widget buildLoadingPage({
 | |
|   bool showAppBar = false,
 | |
|   String routeTitle,
 | |
| }) {
 | |
|   return Scaffold(
 | |
|     appBar: showAppBar
 | |
|         ? AppBar(
 | |
|             title: Text(routeTitle),
 | |
|           )
 | |
|         : null,
 | |
|     body: buildCenteredProgressBar(),
 | |
|   );
 | |
| }
 | |
| 
 | |
| /// Build and return an error card
 | |
| Widget buildErrorCard(String message, {List<Widget> actions}) {
 | |
|   return Card(
 | |
|     elevation: 2.0,
 | |
|     color: Colors.red,
 | |
|     child: Padding(
 | |
|       padding: const EdgeInsets.all(8.0),
 | |
|       child: Row(
 | |
|         children: <Widget>[
 | |
|           Padding(
 | |
|             padding: const EdgeInsets.only(right: 8.0),
 | |
|             child: Icon(
 | |
|               Icons.error,
 | |
|               color: Colors.white,
 | |
|             ),
 | |
|           ),
 | |
|           Flexible(
 | |
|             child: Text(
 | |
|               message,
 | |
|               style: TextStyle(color: Colors.white),
 | |
|               maxLines: null,
 | |
|             ),
 | |
|           ),
 | |
|           Row(
 | |
|             children: actions == null ? <Widget>[] : actions,
 | |
|           )
 | |
|         ],
 | |
|       ),
 | |
|     ),
 | |
|   );
 | |
| }
 | |
| 
 | |
| /// Show an image with a given [url] in full screen
 | |
| void showImageFullScreen(BuildContext context, String url) {
 | |
|   Navigator.of(context).push(MaterialPageRoute(builder: (c) {
 | |
|     // TODO : add better support later
 | |
|     return CachedNetworkImage(
 | |
|       imageUrl: url,
 | |
|     );
 | |
|   }));
 | |
| }
 | |
| 
 | |
| /// Show simple snack
 | |
| void showSimpleSnack(BuildContext context, String message) {
 | |
|   Scaffold.of(context).showSnackBar(SnackBar(content: Text(message)));
 | |
| }
 | |
| 
 | |
| /// Show an alert dialog to ask the user to enter a string
 | |
| ///
 | |
| /// Returns entered string if the dialog is confirmed, null else
 | |
| Future<String> askUserString({
 | |
|   @required BuildContext context,
 | |
|   @required String title,
 | |
|   @required String message,
 | |
|   @required String defaultValue,
 | |
|   @required String hint,
 | |
| }) async {
 | |
|   assert(context != null);
 | |
|   assert(title != null);
 | |
|   assert(message != null);
 | |
|   assert(defaultValue != null);
 | |
|   assert(hint != null);
 | |
| 
 | |
|   TextEditingController controller = TextEditingController(text: defaultValue);
 | |
| 
 | |
|   final confirm = await showDialog<bool>(
 | |
|       context: context,
 | |
|       builder: (c) => AlertDialog(
 | |
|             title: Text(title),
 | |
|             content: Column(
 | |
|               children: <Widget>[
 | |
|                 Text(message),
 | |
|                 TextField(
 | |
|                   controller: controller,
 | |
|                   maxLines: null,
 | |
|                   maxLength: 200,
 | |
|                   keyboardType: TextInputType.text,
 | |
|                   decoration: InputDecoration(
 | |
|                     labelText: hint,
 | |
|                     alignLabelWithHint: true,
 | |
|                   ),
 | |
|                 )
 | |
|               ],
 | |
|             ),
 | |
|             actions: <Widget>[
 | |
|               FlatButton(
 | |
|                 child: Text(tr("Cancel").toUpperCase()),
 | |
|                 onPressed: () => Navigator.pop(c, false),
 | |
|               ),
 | |
|               FlatButton(
 | |
|                 child: Text(tr("OK")),
 | |
|                 onPressed: () => Navigator.pop(c, true),
 | |
|               ),
 | |
|             ],
 | |
|           ));
 | |
| 
 | |
|   if (confirm == null || !confirm) return null;
 | |
| 
 | |
|   return controller.text;
 | |
| }
 | |
| 
 | |
| /// Show an alert dialog to get user confirmation for something
 | |
| ///
 | |
| /// Return value of this function is never null
 | |
| Future<bool> showConfirmDialog({
 | |
|   @required BuildContext context,
 | |
|   String title,
 | |
|   @required String message,
 | |
| }) async {
 | |
|   if (title == null) title = tr("Confirm operation");
 | |
| 
 | |
|   final result = await showDialog<bool>(
 | |
|       context: context,
 | |
|       builder: (c) => AlertDialog(
 | |
|             title: Text(title),
 | |
|             content: Text(message),
 | |
|             actions: <Widget>[
 | |
|               FlatButton(
 | |
|                 onPressed: () => Navigator.pop(context, false),
 | |
|                 child: Text(tr("Cancel").toUpperCase()),
 | |
|               ),
 | |
|               FlatButton(
 | |
|                 onPressed: () => Navigator.pop(context, true),
 | |
|                 child: Text(
 | |
|                   tr("Confirm").toUpperCase(),
 | |
|                   style: TextStyle(color: Colors.red),
 | |
|                 ),
 | |
|               ),
 | |
|             ],
 | |
|           ));
 | |
| 
 | |
|   return result != null && result;
 | |
| }
 | |
| 
 | |
| /// Smart [InputCounterWidgetBuilder] that show text limit only when some
 | |
| /// text has already been entered by the user
 | |
| Widget smartInputCounterWidgetBuilder(
 | |
|   BuildContext context, {
 | |
|   @required int currentLength,
 | |
|   @required int maxLength,
 | |
|   @required bool isFocused,
 | |
| }) =>
 | |
|     currentLength > 0 ? Text("$currentLength/$maxLength") : Container();
 |