Add localizations system
This commit is contained in:
parent
4f4e3a4df5
commit
1f230c0a63
31
README.md
31
README.md
|
@ -23,3 +23,34 @@ Community: [#fluffychat:matrix.org](https://matrix.to/#/#fluffychat:matrix.org)
|
||||||
4. `flutter config --enable-web`
|
4. `flutter config --enable-web`
|
||||||
|
|
||||||
5. `flutter run`
|
5. `flutter run`
|
||||||
|
|
||||||
|
## How to add translations for your language
|
||||||
|
|
||||||
|
1. Replace the non-translated string in the codebase:
|
||||||
|
```
|
||||||
|
Text("Hello world"),
|
||||||
|
```
|
||||||
|
with a method call:
|
||||||
|
```
|
||||||
|
Text(I18n.of(context).helloWorld),
|
||||||
|
```
|
||||||
|
And add the method to `/lib/i18n/i18n.dart`:
|
||||||
|
```
|
||||||
|
String get helloWorld => Intl.message('Hello world');
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Add the string to the .arb files with this command:
|
||||||
|
```
|
||||||
|
flutter pub run intl_translation:extract_to_arb --output-dir=lib/i18n lib/i18n/i18n.dart
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Copy the new translation objects from `/lib/i18n/intl_message.arb` to `/lib/i18n/intl_<yourlanguage>.arb` and translate it or create a new file for your language by copying `intl_message.arb`.
|
||||||
|
|
||||||
|
4. Update the translations with this command:
|
||||||
|
```
|
||||||
|
flutter pub run intl_translation:generate_from_arb \
|
||||||
|
--output-dir=lib/i18n --no-use-deferred-loading \
|
||||||
|
lib/main.dart lib/i18n/intl_*.arb
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Make sure your language is in `supportedLocales` in `/lib/main.dart`.
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:fluffychat/i18n/i18n.dart';
|
||||||
import 'package:fluffychat/views/chat.dart';
|
import 'package:fluffychat/views/chat.dart';
|
||||||
import 'package:fluffychat/views/invitation_selection.dart';
|
import 'package:fluffychat/views/invitation_selection.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
@ -54,7 +55,7 @@ class _NewGroupDialogState extends State<NewGroupDialog> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
title: Text("Create new group"),
|
title: Text(I18n.of(context).createNewGroup),
|
||||||
content: Column(
|
content: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
|
@ -65,12 +66,12 @@ class _NewGroupDialogState extends State<NewGroupDialog> {
|
||||||
textInputAction: TextInputAction.go,
|
textInputAction: TextInputAction.go,
|
||||||
onSubmitted: (s) => submitAction(context),
|
onSubmitted: (s) => submitAction(context),
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: "(Optional) Group name",
|
labelText: I18n.of(context).optionalGroupName,
|
||||||
icon: Icon(Icons.people),
|
icon: Icon(Icons.people),
|
||||||
hintText: "Enter a group name"),
|
hintText: I18n.of(context).enterAGroupName),
|
||||||
),
|
),
|
||||||
SwitchListTile(
|
SwitchListTile(
|
||||||
title: Text("Group is public"),
|
title: Text(I18n.of(context).groupIsPublic),
|
||||||
value: publicGroup,
|
value: publicGroup,
|
||||||
onChanged: (bool b) => setState(() => publicGroup = b),
|
onChanged: (bool b) => setState(() => publicGroup = b),
|
||||||
),
|
),
|
||||||
|
@ -78,14 +79,14 @@ class _NewGroupDialogState extends State<NewGroupDialog> {
|
||||||
),
|
),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
FlatButton(
|
FlatButton(
|
||||||
child: Text("Close".toUpperCase(),
|
child: Text(I18n.of(context).close.toUpperCase(),
|
||||||
style: TextStyle(color: Colors.blueGrey)),
|
style: TextStyle(color: Colors.blueGrey)),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
FlatButton(
|
FlatButton(
|
||||||
child: Text("Create".toUpperCase()),
|
child: Text(I18n.of(context).create.toUpperCase()),
|
||||||
onPressed: () => submitAction(context),
|
onPressed: () => submitAction(context),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -2,6 +2,7 @@ import 'dart:async';
|
||||||
|
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
import 'package:fluffychat/components/avatar.dart';
|
import 'package:fluffychat/components/avatar.dart';
|
||||||
|
import 'package:fluffychat/i18n/i18n.dart';
|
||||||
import 'package:fluffychat/views/chat.dart';
|
import 'package:fluffychat/views/chat.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:share/share.dart';
|
import 'package:share/share.dart';
|
||||||
|
@ -74,12 +75,10 @@ class _NewPrivateChatDialogState extends State<NewPrivateChatDialog> {
|
||||||
"limit": 1,
|
"limit": 1,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
print(response);
|
|
||||||
setState(() => loading = false);
|
setState(() => loading = false);
|
||||||
if (response == false ||
|
if (response == false ||
|
||||||
!(response is Map) ||
|
!(response is Map) ||
|
||||||
(response["results"]?.isEmpty ?? true)) return;
|
(response["results"]?.isEmpty ?? true)) return;
|
||||||
print("Set...");
|
|
||||||
setState(() {
|
setState(() {
|
||||||
foundProfile = response["results"].first;
|
foundProfile = response["results"].first;
|
||||||
});
|
});
|
||||||
|
@ -89,7 +88,7 @@ class _NewPrivateChatDialogState extends State<NewPrivateChatDialog> {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final String defaultDomain = Matrix.of(context).client.userID.split(":")[1];
|
final String defaultDomain = Matrix.of(context).client.userID.split(":")[1];
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
title: Text("New private chat"),
|
title: Text(I18n.of(context).newPrivateChat),
|
||||||
content: Column(
|
content: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
@ -105,23 +104,23 @@ class _NewPrivateChatDialogState extends State<NewPrivateChatDialog> {
|
||||||
onFieldSubmitted: (s) => submitAction(context),
|
onFieldSubmitted: (s) => submitAction(context),
|
||||||
validator: (value) {
|
validator: (value) {
|
||||||
if (value.isEmpty) {
|
if (value.isEmpty) {
|
||||||
return 'Please enter a matrix identifier';
|
return I18n.of(context).pleaseEnterAMatrixIdentifier;
|
||||||
}
|
}
|
||||||
final MatrixState matrix = Matrix.of(context);
|
final MatrixState matrix = Matrix.of(context);
|
||||||
String mxid = "@" + controller.text.trim();
|
String mxid = "@" + controller.text.trim();
|
||||||
if (mxid == matrix.client.userID) {
|
if (mxid == matrix.client.userID) {
|
||||||
return "You cannot invite yourself";
|
return I18n.of(context).youCannotInviteYourself;
|
||||||
}
|
}
|
||||||
if (!mxid.contains("@")) {
|
if (!mxid.contains("@")) {
|
||||||
return "Make sure the identifier is valid";
|
return I18n.of(context).makeSureTheIdentifierIsValid;
|
||||||
}
|
}
|
||||||
if (!mxid.contains(":")) {
|
if (!mxid.contains(":")) {
|
||||||
return "Make sure the identifier is valid";
|
return I18n.of(context).makeSureTheIdentifierIsValid;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: "Enter a username",
|
labelText: I18n.of(context).enterAUsername,
|
||||||
icon: loading
|
icon: loading
|
||||||
? Container(
|
? Container(
|
||||||
width: 24,
|
width: 24,
|
||||||
|
@ -137,7 +136,8 @@ class _NewPrivateChatDialogState extends State<NewPrivateChatDialog> {
|
||||||
)
|
)
|
||||||
: Icon(Icons.account_circle),
|
: Icon(Icons.account_circle),
|
||||||
prefixText: "@",
|
prefixText: "@",
|
||||||
hintText: "username:$defaultDomain",
|
hintText:
|
||||||
|
"${I18n.of(context).username.toLowerCase()}:$defaultDomain",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -179,7 +179,7 @@ class _NewPrivateChatDialogState extends State<NewPrivateChatDialog> {
|
||||||
onTap: () => Share.share(
|
onTap: () => Share.share(
|
||||||
"https://matrix.to/#/${Matrix.of(context).client.userID}"),
|
"https://matrix.to/#/${Matrix.of(context).client.userID}"),
|
||||||
title: Text(
|
title: Text(
|
||||||
"Your own username:",
|
"${I18n.of(context).yourOwnUsername}:",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.blueGrey,
|
color: Colors.blueGrey,
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
|
@ -194,14 +194,14 @@ class _NewPrivateChatDialogState extends State<NewPrivateChatDialog> {
|
||||||
),
|
),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
FlatButton(
|
FlatButton(
|
||||||
child: Text("Close".toUpperCase(),
|
child: Text(I18n.of(context).close.toUpperCase(),
|
||||||
style: TextStyle(color: Colors.blueGrey)),
|
style: TextStyle(color: Colors.blueGrey)),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
FlatButton(
|
FlatButton(
|
||||||
child: Text("Continue".toUpperCase()),
|
child: Text(I18n.of(context).confirm.toUpperCase()),
|
||||||
onPressed: () => submitAction(context),
|
onPressed: () => submitAction(context),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
62
lib/i18n/i18n.dart
Normal file
62
lib/i18n/i18n.dart
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'messages_all.dart';
|
||||||
|
|
||||||
|
class I18n {
|
||||||
|
I18n(this.localeName);
|
||||||
|
|
||||||
|
static Future<I18n> load(Locale locale) {
|
||||||
|
final String name =
|
||||||
|
locale.countryCode.isEmpty ? locale.languageCode : locale.toString();
|
||||||
|
final String localeName = Intl.canonicalizedLocale(name);
|
||||||
|
return initializeMessages(localeName).then((_) {
|
||||||
|
return I18n(localeName);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static I18n of(BuildContext context) {
|
||||||
|
return Localizations.of<I18n>(context, I18n);
|
||||||
|
}
|
||||||
|
|
||||||
|
final String localeName;
|
||||||
|
|
||||||
|
/* <=============> Translations <=============> */
|
||||||
|
|
||||||
|
String get close => Intl.message("Close");
|
||||||
|
|
||||||
|
String get confirm => Intl.message("Confirm");
|
||||||
|
|
||||||
|
String get create => Intl.message("Create");
|
||||||
|
|
||||||
|
String get createNewGroup => Intl.message("Create new group");
|
||||||
|
|
||||||
|
String get enterAGroupName => Intl.message("Enter a group name");
|
||||||
|
|
||||||
|
String get enterAUsername => Intl.message("Enter a username");
|
||||||
|
|
||||||
|
String get groupIsPublic => Intl.message("Group is public");
|
||||||
|
|
||||||
|
String get makeSureTheIdentifierIsValid =>
|
||||||
|
Intl.message("Make sure the identifier is valid");
|
||||||
|
|
||||||
|
String get newPrivateChat => Intl.message("New private chat");
|
||||||
|
|
||||||
|
String get optionalGroupName => Intl.message("(Optional) Group name");
|
||||||
|
|
||||||
|
String get pleaseEnterAMatrixIdentifier =>
|
||||||
|
Intl.message('Please enter a matrix identifier');
|
||||||
|
|
||||||
|
String get title => Intl.message(
|
||||||
|
'FluffyChat',
|
||||||
|
name: 'title',
|
||||||
|
desc: 'Title for the application',
|
||||||
|
locale: localeName,
|
||||||
|
);
|
||||||
|
|
||||||
|
String get username => Intl.message("Username");
|
||||||
|
|
||||||
|
String get youCannotInviteYourself =>
|
||||||
|
Intl.message("You cannot invite yourself");
|
||||||
|
|
||||||
|
String get yourOwnUsername => Intl.message("Your own username");
|
||||||
|
}
|
9
lib/i18n/intl_de.arb
Normal file
9
lib/i18n/intl_de.arb
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"@@last_modified": "2020-01-20T09:30:07.159333",
|
||||||
|
"title": "FluffyChat",
|
||||||
|
"@title": {
|
||||||
|
"description": "Title for the application",
|
||||||
|
"type": "text",
|
||||||
|
"placeholders": {}
|
||||||
|
}
|
||||||
|
}
|
79
lib/i18n/intl_messages.arb
Normal file
79
lib/i18n/intl_messages.arb
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
{
|
||||||
|
"@@last_modified": "2020-01-20T09:50:21.386565",
|
||||||
|
"Close": "Close",
|
||||||
|
"@Close": {
|
||||||
|
"type": "text",
|
||||||
|
"placeholders": {}
|
||||||
|
},
|
||||||
|
"Confirm": "Confirm",
|
||||||
|
"@Confirm": {
|
||||||
|
"type": "text",
|
||||||
|
"placeholders": {}
|
||||||
|
},
|
||||||
|
"Create": "Create",
|
||||||
|
"@Create": {
|
||||||
|
"type": "text",
|
||||||
|
"placeholders": {}
|
||||||
|
},
|
||||||
|
"Create new group": "Create new group",
|
||||||
|
"@Create new group": {
|
||||||
|
"type": "text",
|
||||||
|
"placeholders": {}
|
||||||
|
},
|
||||||
|
"Enter a group name": "Enter a group name",
|
||||||
|
"@Enter a group name": {
|
||||||
|
"type": "text",
|
||||||
|
"placeholders": {}
|
||||||
|
},
|
||||||
|
"Enter a username": "Enter a username",
|
||||||
|
"@Enter a username": {
|
||||||
|
"type": "text",
|
||||||
|
"placeholders": {}
|
||||||
|
},
|
||||||
|
"Group is public": "Group is public",
|
||||||
|
"@Group is public": {
|
||||||
|
"type": "text",
|
||||||
|
"placeholders": {}
|
||||||
|
},
|
||||||
|
"Make sure the identifier is valid": "Make sure the identifier is valid",
|
||||||
|
"@Make sure the identifier is valid": {
|
||||||
|
"type": "text",
|
||||||
|
"placeholders": {}
|
||||||
|
},
|
||||||
|
"New private chat": "New private chat",
|
||||||
|
"@New private chat": {
|
||||||
|
"type": "text",
|
||||||
|
"placeholders": {}
|
||||||
|
},
|
||||||
|
"(Optional) Group name": "(Optional) Group name",
|
||||||
|
"@(Optional) Group name": {
|
||||||
|
"type": "text",
|
||||||
|
"placeholders": {}
|
||||||
|
},
|
||||||
|
"Please enter a matrix identifier": "Please enter a matrix identifier",
|
||||||
|
"@Please enter a matrix identifier": {
|
||||||
|
"type": "text",
|
||||||
|
"placeholders": {}
|
||||||
|
},
|
||||||
|
"title": "FluffyChat",
|
||||||
|
"@title": {
|
||||||
|
"description": "Title for the application",
|
||||||
|
"type": "text",
|
||||||
|
"placeholders": {}
|
||||||
|
},
|
||||||
|
"Username": "Username",
|
||||||
|
"@Username": {
|
||||||
|
"type": "text",
|
||||||
|
"placeholders": {}
|
||||||
|
},
|
||||||
|
"You cannot invite yourself": "You cannot invite yourself",
|
||||||
|
"@You cannot invite yourself": {
|
||||||
|
"type": "text",
|
||||||
|
"placeholders": {}
|
||||||
|
},
|
||||||
|
"Your own username": "Your own username",
|
||||||
|
"@Your own username": {
|
||||||
|
"type": "text",
|
||||||
|
"placeholders": {}
|
||||||
|
}
|
||||||
|
}
|
67
lib/i18n/messages_all.dart
Normal file
67
lib/i18n/messages_all.dart
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
|
||||||
|
// This is a library that looks up messages for specific locales by
|
||||||
|
// delegating to the appropriate library.
|
||||||
|
|
||||||
|
// Ignore issues from commonly used lints in this file.
|
||||||
|
// ignore_for_file:implementation_imports, file_names, unnecessary_new
|
||||||
|
// ignore_for_file:unnecessary_brace_in_string_interps, directives_ordering
|
||||||
|
// ignore_for_file:argument_type_not_assignable, invalid_assignment
|
||||||
|
// ignore_for_file:prefer_single_quotes, prefer_generic_function_type_aliases
|
||||||
|
// ignore_for_file:comment_references
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:intl/message_lookup_by_library.dart';
|
||||||
|
import 'package:intl/src/intl_helpers.dart';
|
||||||
|
|
||||||
|
import 'messages_de.dart' as messages_de;
|
||||||
|
import 'messages_messages.dart' as messages_messages;
|
||||||
|
|
||||||
|
typedef Future<dynamic> LibraryLoader();
|
||||||
|
Map<String, LibraryLoader> _deferredLibraries = {
|
||||||
|
'de': () => new Future.value(null),
|
||||||
|
'messages': () => new Future.value(null),
|
||||||
|
};
|
||||||
|
|
||||||
|
MessageLookupByLibrary _findExact(String localeName) {
|
||||||
|
switch (localeName) {
|
||||||
|
case 'de':
|
||||||
|
return messages_de.messages;
|
||||||
|
case 'messages':
|
||||||
|
return messages_messages.messages;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// User programs should call this before using [localeName] for messages.
|
||||||
|
Future<bool> initializeMessages(String localeName) async {
|
||||||
|
var availableLocale = Intl.verifiedLocale(
|
||||||
|
localeName,
|
||||||
|
(locale) => _deferredLibraries[locale] != null,
|
||||||
|
onFailure: (_) => null);
|
||||||
|
if (availableLocale == null) {
|
||||||
|
return new Future.value(false);
|
||||||
|
}
|
||||||
|
var lib = _deferredLibraries[availableLocale];
|
||||||
|
await (lib == null ? new Future.value(false) : lib());
|
||||||
|
initializeInternalMessageLookup(() => new CompositeMessageLookup());
|
||||||
|
messageLookup.addLocale(availableLocale, _findGeneratedMessagesFor);
|
||||||
|
return new Future.value(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _messagesExistFor(String locale) {
|
||||||
|
try {
|
||||||
|
return _findExact(locale) != null;
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageLookupByLibrary _findGeneratedMessagesFor(String locale) {
|
||||||
|
var actualLocale = Intl.verifiedLocale(locale, _messagesExistFor,
|
||||||
|
onFailure: (_) => null);
|
||||||
|
if (actualLocale == null) return null;
|
||||||
|
return _findExact(actualLocale);
|
||||||
|
}
|
26
lib/i18n/messages_de.dart
Normal file
26
lib/i18n/messages_de.dart
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
|
||||||
|
// This is a library that provides messages for a de locale. All the
|
||||||
|
// messages from the main program should be duplicated here with the same
|
||||||
|
// function name.
|
||||||
|
|
||||||
|
// Ignore issues from commonly used lints in this file.
|
||||||
|
// ignore_for_file:unnecessary_brace_in_string_interps, unnecessary_new
|
||||||
|
// ignore_for_file:prefer_single_quotes,comment_references, directives_ordering
|
||||||
|
// ignore_for_file:annotate_overrides,prefer_generic_function_type_aliases
|
||||||
|
// ignore_for_file:unused_import, file_names
|
||||||
|
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:intl/message_lookup_by_library.dart';
|
||||||
|
|
||||||
|
final messages = new MessageLookup();
|
||||||
|
|
||||||
|
typedef String MessageIfAbsent(String messageStr, List<dynamic> args);
|
||||||
|
|
||||||
|
class MessageLookup extends MessageLookupByLibrary {
|
||||||
|
String get localeName => 'de';
|
||||||
|
|
||||||
|
final messages = _notInlinedMessages(_notInlinedMessages);
|
||||||
|
static _notInlinedMessages(_) => <String, Function> {
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
26
lib/i18n/messages_messages.dart
Normal file
26
lib/i18n/messages_messages.dart
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
|
||||||
|
// This is a library that provides messages for a messages locale. All the
|
||||||
|
// messages from the main program should be duplicated here with the same
|
||||||
|
// function name.
|
||||||
|
|
||||||
|
// Ignore issues from commonly used lints in this file.
|
||||||
|
// ignore_for_file:unnecessary_brace_in_string_interps, unnecessary_new
|
||||||
|
// ignore_for_file:prefer_single_quotes,comment_references, directives_ordering
|
||||||
|
// ignore_for_file:annotate_overrides,prefer_generic_function_type_aliases
|
||||||
|
// ignore_for_file:unused_import, file_names
|
||||||
|
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:intl/message_lookup_by_library.dart';
|
||||||
|
|
||||||
|
final messages = new MessageLookup();
|
||||||
|
|
||||||
|
typedef String MessageIfAbsent(String messageStr, List<dynamic> args);
|
||||||
|
|
||||||
|
class MessageLookup extends MessageLookupByLibrary {
|
||||||
|
String get localeName => 'messages';
|
||||||
|
|
||||||
|
final messages = _notInlinedMessages(_notInlinedMessages);
|
||||||
|
static _notInlinedMessages(_) => <String, Function> {
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ import 'package:famedlysdk/famedlysdk.dart';
|
||||||
import 'package:fluffychat/views/sign_up.dart';
|
import 'package:fluffychat/views/sign_up.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||||
|
|
||||||
import 'components/matrix.dart';
|
import 'components/matrix.dart';
|
||||||
import 'views/chat_list.dart';
|
import 'views/chat_list.dart';
|
||||||
|
@ -46,6 +47,15 @@ class App extends StatelessWidget {
|
||||||
iconTheme: IconThemeData(color: Colors.black),
|
iconTheme: IconThemeData(color: Colors.black),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
localizationsDelegates: [
|
||||||
|
GlobalMaterialLocalizations.delegate,
|
||||||
|
GlobalWidgetsLocalizations.delegate,
|
||||||
|
GlobalCupertinoLocalizations.delegate,
|
||||||
|
],
|
||||||
|
supportedLocales: [
|
||||||
|
const Locale('en'), // English
|
||||||
|
const Locale('de'), // German
|
||||||
|
],
|
||||||
home: Builder(
|
home: Builder(
|
||||||
builder: (BuildContext context) => FutureBuilder<LoginState>(
|
builder: (BuildContext context) => FutureBuilder<LoginState>(
|
||||||
future: Matrix.of(context).client.onLoginStateChanged.stream.first,
|
future: Matrix.of(context).client.onLoginStateChanged.stream.first,
|
||||||
|
|
103
pubspec.lock
103
pubspec.lock
|
@ -1,6 +1,20 @@
|
||||||
# Generated by pub
|
# Generated by pub
|
||||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||||
packages:
|
packages:
|
||||||
|
_fe_analyzer_shared:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: _fe_analyzer_shared
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.3"
|
||||||
|
analyzer:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: analyzer
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.39.4"
|
||||||
archive:
|
archive:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -71,6 +85,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.3"
|
version: "2.1.3"
|
||||||
|
csslib:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: csslib
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.16.1"
|
||||||
cupertino_icons:
|
cupertino_icons:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -78,6 +99,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.3"
|
version: "0.1.3"
|
||||||
|
dart_style:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: dart_style
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.3.3"
|
||||||
famedlysdk:
|
famedlysdk:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -127,6 +155,11 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.9.1+2"
|
version: "0.9.1+2"
|
||||||
|
flutter_localizations:
|
||||||
|
dependency: "direct main"
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
flutter_speed_dial:
|
flutter_speed_dial:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -144,6 +177,20 @@ packages:
|
||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
glob:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: glob
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.2.0"
|
||||||
|
html:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: html
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.14.0+3"
|
||||||
http:
|
http:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -172,6 +219,27 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.2+3"
|
version: "0.6.2+3"
|
||||||
|
intl:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: intl
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.16.0"
|
||||||
|
intl_translation:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: intl_translation
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.17.9"
|
||||||
|
js:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: js
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.6.1+1"
|
||||||
json_annotation:
|
json_annotation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -214,6 +282,27 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.2.4"
|
version: "0.2.4"
|
||||||
|
node_interop:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: node_interop
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.3"
|
||||||
|
node_io:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: node_io
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.1+2"
|
||||||
|
package_config:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: package_config
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.0"
|
||||||
path:
|
path:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -256,6 +345,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.1"
|
version: "1.0.1"
|
||||||
|
pub_semver:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: pub_semver
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.2"
|
||||||
quiver:
|
quiver:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -394,6 +490,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.8"
|
version: "2.0.8"
|
||||||
|
watcher:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: watcher
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.9.7+13"
|
||||||
webview_flutter:
|
webview_flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -47,6 +47,11 @@ dependencies:
|
||||||
share: ^0.6.3+5
|
share: ^0.6.3+5
|
||||||
receive_sharing_intent: ^1.3.2
|
receive_sharing_intent: ^1.3.2
|
||||||
|
|
||||||
|
intl: ^0.16.0
|
||||||
|
intl_translation: ^0.17.9
|
||||||
|
flutter_localizations:
|
||||||
|
sdk: flutter
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
Loading…
Reference in a new issue