mirror of
https://gitlab.com/openlp/openlp-mobile-remote.git
synced 2024-12-22 11:52:49 +00:00
app localization structure
This commit is contained in:
parent
9270ade460
commit
fec650f970
43
lang/en.json
Normal file
43
lang/en.json
Normal file
@ -0,0 +1,43 @@
|
||||
{
|
||||
"tab_service": "SERVICE",
|
||||
"tab_slides": "SLIDES",
|
||||
"floating_button_search": "New service item",
|
||||
"button_cancel": "CANCEL",
|
||||
"button_show": "SHOW",
|
||||
"button_ok": "OK",
|
||||
"alert": "Alert",
|
||||
"dialog_alert_title": "Type your alert",
|
||||
"display": "Display",
|
||||
"display_option_blank": "Blank screen",
|
||||
"display_option_theme": "Theme background",
|
||||
"display_option_desktop": "Desktop",
|
||||
"display_option_show": "Full projection",
|
||||
"plugin_songs_singular": "Song",
|
||||
"plugin_songs_plural": "Songs",
|
||||
"plugin_bibles_singular": "Bible",
|
||||
"plugin_bibles_plural": "Bibles",
|
||||
"plugin_presentations_singular": "Presentation",
|
||||
"plugin_presentations_plural": "Presentations",
|
||||
"plugin_images_singular": "Image",
|
||||
"plugin_images_plural": "Images",
|
||||
"plugin_media_singular": "Media",
|
||||
"plugin_media_plural": "Medias",
|
||||
"plugin_custom_singular": "Custom",
|
||||
"plugin_custom_plural": "Customs",
|
||||
"search_results_go": "Go live",
|
||||
"search_results_add": "Add to service",
|
||||
"search_results_add_and_go": "Add & Go to service",
|
||||
"service_list_empty": "Any item added to service.\nPlease, add a new service item tapping the add button.",
|
||||
"settings": "Settings",
|
||||
"settings_server_ip": "Server IP",
|
||||
"settings_server_port": "Server port",
|
||||
"settings_use_https": "User HTTPS",
|
||||
"settings_needs_auth": "Needs auth",
|
||||
"settings_user_id": "User ID",
|
||||
"settings_user_pass": "User password",
|
||||
"settings_about_openlp": "About OpenLP",
|
||||
"dialog_server_ip_title": "Type the IP",
|
||||
"dialog_server_port_title": "Type the port",
|
||||
"dialog_server_user_id_title": "Type the ID",
|
||||
"dialog_server_user_pass_title": "Type the password"
|
||||
}
|
3
lang/pt.json
Normal file
3
lang/pt.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"tab_service_label": "CULTO"
|
||||
}
|
@ -21,15 +21,36 @@
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
|
||||
import 'src/openlp_mobile_remote_app.dart';
|
||||
import 'src/app_theme.dart';
|
||||
import 'src/configurations/app_theme.dart';
|
||||
import 'src/configurations/app_localizations.dart';
|
||||
import 'src/screens/settings.dart';
|
||||
|
||||
void main() => runApp(
|
||||
MaterialApp(
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: appTheme,
|
||||
supportedLocales: [
|
||||
Locale('en'),
|
||||
Locale('pt'),
|
||||
],
|
||||
localizationsDelegates: [
|
||||
AppLocalizations.delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
],
|
||||
localeResolutionCallback: (locale, supportedLocales) {
|
||||
for (var supportedLocale in supportedLocales) {
|
||||
if (supportedLocale.languageCode == locale.languageCode) {
|
||||
// if (supportedLocale.countryCode == locale.countryCode) {
|
||||
return supportedLocale;
|
||||
// }
|
||||
}
|
||||
}
|
||||
return supportedLocales.first;
|
||||
},
|
||||
routes: <String, WidgetBuilder>{
|
||||
'/': (context) => OpenLPMobileRemoteApp(),
|
||||
'/settings': (context) => Settings(),
|
||||
|
56
lib/src/configurations/app_localizations.dart
Normal file
56
lib/src/configurations/app_localizations.dart
Normal file
@ -0,0 +1,56 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
class AppLocalizations {
|
||||
final Locale locale;
|
||||
|
||||
AppLocalizations(this.locale);
|
||||
|
||||
static AppLocalizations of(BuildContext context) =>
|
||||
Localizations.of<AppLocalizations>(context, AppLocalizations);
|
||||
|
||||
Map<String, String> _localizedString;
|
||||
|
||||
Future<void> load() async {
|
||||
String jsonFileName = 'lang/${locale.languageCode}';
|
||||
if (locale.countryCode != null) {
|
||||
jsonFileName += '_${locale.countryCode}';
|
||||
}
|
||||
jsonFileName += '.json';
|
||||
|
||||
String mainJsonString = await rootBundle.loadString('lang/en.json');
|
||||
Map<String, dynamic> jsonMap = json.decode(mainJsonString);
|
||||
|
||||
String localizedJsonString = await rootBundle.loadString(jsonFileName);
|
||||
jsonMap.addAll(json.decode(localizedJsonString));
|
||||
|
||||
_localizedString =
|
||||
jsonMap.map((key, value) => MapEntry(key, value.toString()));
|
||||
}
|
||||
|
||||
String translate(String key) => _localizedString[key];
|
||||
|
||||
static const LocalizationsDelegate<AppLocalizations> delegate =
|
||||
_AppLocalizationsDelegate();
|
||||
}
|
||||
|
||||
class _AppLocalizationsDelegate
|
||||
extends LocalizationsDelegate<AppLocalizations> {
|
||||
const _AppLocalizationsDelegate();
|
||||
|
||||
@override
|
||||
bool isSupported(Locale locale) => true;
|
||||
|
||||
@override
|
||||
Future<AppLocalizations> load(Locale locale) async {
|
||||
AppLocalizations localizations = new AppLocalizations(locale);
|
||||
await localizations.load();
|
||||
return localizations;
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldReload(_AppLocalizationsDelegate old) => false;
|
||||
}
|
@ -22,6 +22,8 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../resources/openlp_icons.dart';
|
||||
|
||||
class Plugin {
|
||||
final String id;
|
||||
|
||||
@ -30,17 +32,17 @@ class Plugin {
|
||||
IconData icon() {
|
||||
switch (this.id) {
|
||||
case 'songs':
|
||||
return Icons.audiotrack;
|
||||
return OpenLPIcons.songs;
|
||||
case 'bibles':
|
||||
return Icons.book;
|
||||
return OpenLPIcons.biblies;
|
||||
case 'presentations':
|
||||
return Icons.present_to_all;
|
||||
return OpenLPIcons.presentations;
|
||||
case 'images':
|
||||
return Icons.image;
|
||||
return OpenLPIcons.images;
|
||||
case 'media':
|
||||
return Icons.ondemand_video;
|
||||
return OpenLPIcons.media;
|
||||
case 'custom':
|
||||
return Icons.video_label;
|
||||
return OpenLPIcons.custom;
|
||||
}
|
||||
return Icons.screen_share;
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:openlp_remote/src/configurations/app_localizations.dart';
|
||||
|
||||
import 'widgets/bottom_navigation_bar.dart';
|
||||
import 'widgets/search_floating_button.dart';
|
||||
@ -58,8 +59,8 @@ class _OpenLPMobileRemoteAppState extends State<OpenLPMobileRemoteApp>
|
||||
],
|
||||
bottom: TabBar(
|
||||
tabs: <Widget>[
|
||||
Tab(text: 'SERVICE'),
|
||||
Tab(text: 'SLIDES'),
|
||||
Tab(text: AppLocalizations.of(context).translate('tab_service')),
|
||||
Tab(text: AppLocalizations.of(context).translate('tab_slides')),
|
||||
],
|
||||
controller: tabController,
|
||||
),
|
||||
|
@ -23,9 +23,10 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class OpenLPIcons {
|
||||
final IconData songs = Icons.audiotrack;
|
||||
final IconData biblies = Icons.book;
|
||||
final IconData presentations = Icons.present_to_all;
|
||||
final IconData media = Icons.ondemand_video;
|
||||
final IconData custom = Icons.video_label;
|
||||
static final IconData songs = Icons.audiotrack;
|
||||
static final IconData biblies = Icons.book;
|
||||
static final IconData images = Icons.image;
|
||||
static final IconData presentations = Icons.present_to_all;
|
||||
static final IconData media = Icons.ondemand_video;
|
||||
static final IconData custom = Icons.video_label;
|
||||
}
|
||||
|
@ -22,6 +22,8 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../configurations/app_localizations.dart';
|
||||
|
||||
class SearchServiceItem extends SearchDelegate {
|
||||
@override
|
||||
List<Widget> buildActions(BuildContext context) {
|
||||
@ -54,20 +56,23 @@ class SearchServiceItem extends SearchDelegate {
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: Text('Go live'),
|
||||
title: Text(
|
||||
AppLocalizations.of(context).translate('search_results_go')),
|
||||
onTap: () {
|
||||
Navigator.of(context).pop();
|
||||
close(context, null);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: Text('Add to service'),
|
||||
title: Text(
|
||||
AppLocalizations.of(context).translate('search_results_add')),
|
||||
onTap: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: Text('Add & Go to service'),
|
||||
title: Text(AppLocalizations.of(context)
|
||||
.translate('search_results_add_and_go')),
|
||||
onTap: () {
|
||||
Navigator.of(context).pop();
|
||||
close(context, null);
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../configurations/app_localizations.dart';
|
||||
import '../models/service_item.dart';
|
||||
|
||||
class ServiceListView extends StatefulWidget {
|
||||
@ -64,8 +65,7 @@ class _ServiceListViewState extends State<ServiceListView> {
|
||||
maxWidth: 250,
|
||||
),
|
||||
child: Text(
|
||||
'Any item added to service.\n' +
|
||||
'Please, add a new service item tapping the "New service item" button.',
|
||||
AppLocalizations.of(context).translate('service_list_empty'),
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(color: Colors.black38),
|
||||
),
|
||||
@ -94,7 +94,8 @@ class _ServiceListViewState extends State<ServiceListView> {
|
||||
),
|
||||
),
|
||||
title: Text(item.title),
|
||||
subtitle: Text(item.plugin.id),
|
||||
subtitle: Text(AppLocalizations.of(context)
|
||||
.translate('plugin_${item.plugin.id}_singular')),
|
||||
trailing: IconButton(
|
||||
icon: Icon(Icons.delete),
|
||||
onPressed: () {},
|
||||
|
@ -23,6 +23,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
import '../configurations/app_localizations.dart';
|
||||
|
||||
class Settings extends StatefulWidget {
|
||||
@override
|
||||
@ -52,32 +53,37 @@ class _SettingState extends State<Settings> {
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text('Settings'),
|
||||
title: Text(AppLocalizations.of(context).translate('settings')),
|
||||
),
|
||||
body: ListView(
|
||||
children: <Widget>[
|
||||
ListTile(
|
||||
title: Text('Server IP'),
|
||||
title: Text(
|
||||
AppLocalizations.of(context).translate('settings_server_ip')),
|
||||
subtitle: Text(serverIp),
|
||||
onTap: () {
|
||||
showDialog<String>(
|
||||
context: context,
|
||||
builder: (context) => _InputDialog('Type the IP'),
|
||||
builder: (context) => _InputDialog(AppLocalizations.of(context)
|
||||
.translate('dialog_server_ip_title')),
|
||||
);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: Text('Server port'),
|
||||
title: Text(
|
||||
AppLocalizations.of(context).translate('settings_server_port')),
|
||||
subtitle: Text('$serverPort'),
|
||||
onTap: () {
|
||||
showDialog<String>(
|
||||
context: context,
|
||||
builder: (context) => _InputDialog('Type the port'),
|
||||
builder: (context) => _InputDialog(AppLocalizations.of(context)
|
||||
.translate('dialog_server_port_title')),
|
||||
);
|
||||
},
|
||||
),
|
||||
CheckboxListTile(
|
||||
title: Text('Use HTTPS'),
|
||||
title: Text(
|
||||
AppLocalizations.of(context).translate('settings_use_https')),
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
useHttps = value;
|
||||
@ -87,7 +93,8 @@ class _SettingState extends State<Settings> {
|
||||
),
|
||||
Divider(),
|
||||
CheckboxListTile(
|
||||
title: Text('Needs auth'),
|
||||
title: Text(
|
||||
AppLocalizations.of(context).translate('settings_needs_auth')),
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
needsAuth = value;
|
||||
@ -97,29 +104,34 @@ class _SettingState extends State<Settings> {
|
||||
),
|
||||
ListTile(
|
||||
enabled: needsAuth,
|
||||
title: Text('User ID'),
|
||||
title: Text(
|
||||
AppLocalizations.of(context).translate('settings_user_id')),
|
||||
subtitle: Text(userId),
|
||||
onTap: () {
|
||||
showDialog<String>(
|
||||
context: context,
|
||||
builder: (context) => _InputDialog('Type the username'),
|
||||
builder: (context) => _InputDialog(AppLocalizations.of(context)
|
||||
.translate('dialog_server_user_id_title')),
|
||||
);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
enabled: needsAuth,
|
||||
title: Text('User password'),
|
||||
title: Text(
|
||||
AppLocalizations.of(context).translate('settings_user_pass')),
|
||||
subtitle: Text(userPassword),
|
||||
onTap: () {
|
||||
showDialog<String>(
|
||||
context: context,
|
||||
builder: (context) => _InputDialog('Type the password'),
|
||||
builder: (context) => _InputDialog(AppLocalizations.of(context)
|
||||
.translate('dialog_server_user_pass_title')),
|
||||
);
|
||||
},
|
||||
),
|
||||
Divider(),
|
||||
ListTile(
|
||||
title: Text('About OpenLP'),
|
||||
title: Text(AppLocalizations.of(context)
|
||||
.translate('settings_about_openlp')),
|
||||
onTap: () {
|
||||
launch('https://openlp.org/');
|
||||
},
|
||||
@ -143,13 +155,13 @@ class _InputDialog extends StatelessWidget {
|
||||
content: TextField(autofocus: true),
|
||||
actions: <Widget>[
|
||||
FlatButton(
|
||||
child: Text('CANCEL'),
|
||||
child: Text(AppLocalizations.of(context).translate('button_cancel')),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
FlatButton(
|
||||
child: Text('OK'),
|
||||
child: Text(AppLocalizations.of(context).translate('button_ok')),
|
||||
onPressed: () {
|
||||
Navigator.pop(context, '');
|
||||
},
|
||||
|
@ -22,6 +22,8 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../configurations/app_localizations.dart';
|
||||
|
||||
import 'display_options_dialog.dart';
|
||||
import 'show_alert_dialog.dart';
|
||||
|
||||
@ -36,18 +38,26 @@ class AppBottomNavigationBar extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final List<_Action> _actions = [
|
||||
_Action(Icons.add_alert, 'Alert', () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => ShowAlertDialog(),
|
||||
);
|
||||
}),
|
||||
_Action(Icons.personal_video, 'Display', () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => DisplayOptionsDialog(),
|
||||
);
|
||||
}),
|
||||
_Action(
|
||||
Icons.add_alert,
|
||||
AppLocalizations.of(context).translate('alert'),
|
||||
() {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => ShowAlertDialog(),
|
||||
);
|
||||
},
|
||||
),
|
||||
_Action(
|
||||
Icons.personal_video,
|
||||
AppLocalizations.of(context).translate('display'),
|
||||
() {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => DisplayOptionsDialog(),
|
||||
);
|
||||
},
|
||||
),
|
||||
];
|
||||
return BottomAppBar(
|
||||
child: Row(
|
||||
|
@ -22,26 +22,40 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../configurations/app_localizations.dart';
|
||||
|
||||
class _Action {
|
||||
String title;
|
||||
String titleKey;
|
||||
VoidCallback callback;
|
||||
_Action(this.title, this.callback);
|
||||
_Action({@required this.titleKey, @required this.callback});
|
||||
}
|
||||
|
||||
class DisplayOptionsDialog extends StatelessWidget {
|
||||
final List<_Action> _actions = [
|
||||
_Action('Blank screen', () {
|
||||
print('Blank screen');
|
||||
}),
|
||||
_Action('Theme background', () {
|
||||
print('Theme screen');
|
||||
}),
|
||||
_Action('Desktop', () {
|
||||
print('Desktop screen');
|
||||
}),
|
||||
_Action('Full projection', () {
|
||||
print('Show screen');
|
||||
}),
|
||||
_Action(
|
||||
titleKey: 'display_option_blank',
|
||||
callback: () {
|
||||
print('Blank screen');
|
||||
},
|
||||
),
|
||||
_Action(
|
||||
titleKey: 'display_option_theme',
|
||||
callback: () {
|
||||
print('Theme screen');
|
||||
},
|
||||
),
|
||||
_Action(
|
||||
titleKey: 'display_option_desktop',
|
||||
callback: () {
|
||||
print('Desktop screen');
|
||||
},
|
||||
),
|
||||
_Action(
|
||||
titleKey: 'display_option_show',
|
||||
callback: () {
|
||||
print('Show screen');
|
||||
},
|
||||
),
|
||||
];
|
||||
|
||||
@override
|
||||
@ -52,7 +66,8 @@ class DisplayOptionsDialog extends StatelessWidget {
|
||||
.map((action) => OutlineButton(
|
||||
borderSide: BorderSide(color: Theme.of(context).primaryColor),
|
||||
textColor: Theme.of(context).primaryColor,
|
||||
child: Text(action.title),
|
||||
child: Text(
|
||||
AppLocalizations.of(context).translate(action.titleKey)),
|
||||
onPressed: () {
|
||||
action.callback();
|
||||
Navigator.of(context).pop();
|
||||
|
@ -22,18 +22,20 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../widgets/service_item_bottom_sheet.dart';
|
||||
import '../configurations/app_localizations.dart';
|
||||
import '../widgets/select_service_item_bottom_sheet.dart';
|
||||
|
||||
class SearchFloatingButton extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return FloatingActionButton.extended(
|
||||
label: Text('New service item'),
|
||||
label: Text(AppLocalizations.of(context)
|
||||
.translate('floating_button_search')),
|
||||
icon: Icon(Icons.search),
|
||||
onPressed: () {
|
||||
showModalBottomSheet<void>(
|
||||
context: context,
|
||||
builder: (context) => ServiceItemBottomSheet(),
|
||||
builder: (context) => SelectServiceItemBottomSheet(),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
@ -22,21 +22,24 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../configurations/app_localizations.dart';
|
||||
import '../resources/openlp_icons.dart';
|
||||
import '../screens/search_service_item.dart';
|
||||
|
||||
class _ServiceItem {
|
||||
IconData icon;
|
||||
String title;
|
||||
_ServiceItem({this.icon, this.title});
|
||||
String titleKey;
|
||||
_ServiceItem({@required this.icon, @required this.titleKey});
|
||||
}
|
||||
|
||||
class ServiceItemBottomSheet extends StatelessWidget {
|
||||
class SelectServiceItemBottomSheet extends StatelessWidget {
|
||||
final List<_ServiceItem> _serviceItems = [
|
||||
_ServiceItem(icon: Icons.audiotrack, title: 'Songs'),
|
||||
_ServiceItem(icon: Icons.book, title: 'Bibles'),
|
||||
_ServiceItem(icon: Icons.present_to_all, title: 'Presentations'),
|
||||
_ServiceItem(icon: Icons.image, title: 'Images'),
|
||||
_ServiceItem(icon: Icons.ondemand_video, title: 'Medias'),
|
||||
_ServiceItem(icon: OpenLPIcons.songs, titleKey: 'plugin_songs_plural'),
|
||||
_ServiceItem(icon: OpenLPIcons.biblies, titleKey: 'plugin_bibles_plural'),
|
||||
_ServiceItem(icon: OpenLPIcons.presentations, titleKey: 'plugin_presentations_plural'),
|
||||
_ServiceItem(icon: OpenLPIcons.images, titleKey: 'plugin_images_plural'),
|
||||
_ServiceItem(icon: OpenLPIcons.media, titleKey: 'plugin_media_plural'),
|
||||
_ServiceItem(icon: OpenLPIcons.custom, titleKey: 'plugin_custom_plural'),
|
||||
];
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -45,7 +48,7 @@ class ServiceItemBottomSheet extends StatelessWidget {
|
||||
children: _serviceItems.map((item) {
|
||||
return ListTile(
|
||||
leading: Icon(item.icon),
|
||||
title: Text(item.title),
|
||||
title: Text(AppLocalizations.of(context).translate(item.titleKey)),
|
||||
onTap: () {
|
||||
Navigator.of(context).pop();
|
||||
showSearch(context: context, delegate: SearchServiceItem());
|
@ -22,20 +22,22 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../configurations/app_localizations.dart';
|
||||
|
||||
class ShowAlertDialog extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: Text('Type your alert'),
|
||||
title: Text(AppLocalizations.of(context).translate('dialog_alert_title')),
|
||||
actions: <Widget>[
|
||||
FlatButton(
|
||||
child: Text('Cancel'),
|
||||
child: Text(AppLocalizations.of(context).translate('button_cancel')),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
FlatButton(
|
||||
child: Text('Show'),
|
||||
child: Text(AppLocalizations.of(context).translate('button_show')),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
|
@ -42,6 +42,8 @@ dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
url_launcher: ^5.1.2
|
||||
flutter_localizations:
|
||||
sdk: flutter
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
@ -60,9 +62,9 @@ flutter:
|
||||
uses-material-design: true
|
||||
|
||||
# To add assets to your application, add an assets section, like this:
|
||||
# assets:
|
||||
# - images/a_dot_burr.jpeg
|
||||
# - images/a_dot_ham.jpeg
|
||||
assets:
|
||||
- lang/en.json
|
||||
- lang/pt.json
|
||||
|
||||
# An image asset can refer to one or more resolution-specific "variants", see
|
||||
# https://flutter.dev/assets-and-images/#resolution-aware.
|
||||
|
Loading…
Reference in New Issue
Block a user